#reactjs #redux #react-redux
#reactjs #redux #реагировать-redux
Вопрос:
У меня есть эти редукторы:
const initialState = {
categories: [],
programms: {}
}
export const programmReducers = (state = initialState, action) => {
let programms = state.programms;
switch (action.type) {
case actionTypes.FETCH_CATEGORIES:
return Object.assign({}, state, {
categories: action.payload
})
case actionTypes.FETCH_PROGRAMM:
programms[action.payload.id] = action.payload;
console.log(programms);
return {
...state,
programms: Object.assign({}, programms)
}
case actionTypes.FETCH_PROGRAMM_COMPONENTS:
programms[action.programmId].components = action.payload;
console.log('Added Components')
return {
...state,
programms: programms
}
default:
return state
}
}
Последний ( FETCH_PROGRAMM_COMPONENTS
) добавляет массив к объекту в programm object. Это работает, но почему-то это не сработает componentDidUpdate
в моем компоненте. Хотя это работает для FETCH_PROGRAMM
.
class ProgrammPage extends Component {
static async getInitialProps({ store, query: {id} }) {
let programm;
if (!store.getState().programm.programms[id]) {
console.log('Programm not! found');
programm = await store.dispatch(loadProgramm(id));
await store.dispatch(loadProgrammComponents(id));
} else {
programm = store.getState().programm.programms[id];
console.log('Programm found')
}
return {
// programm: programm
programmId: id
}
}
componentDidUpdate(prevProps) {
console.log('UPDATE', this.props, this.props.programm.components.length)
if (!prevProps.user amp;amp; this.props.user) {
this.props.loadProgrammComponents(this.props.programmId);
}
}
render() {
return (
<div>
<h1>Programm</h1>
<h2>{this.props.programm.name}</h2>
<h2>{this.props.programm.id}</h2>
<h3>Components: {this.props.programm.components ? this.props.programm.components.length : 'None'}</h3>
<br></br>
<h1>User: { this.props.user ? this.props.user.uid : 'None'}</h1>
<button onClick={() => this.props.loadProgramm('ProgrammLevel2')}>Load Programm</button>
<button onClick={() => this.props.loadProgrammComponents(this.props.programmId)}>Load Components</button>
</div>
)
}
}
function mapStateToProps(state) {
return {
programm: state.programm.programms['ProgrammLevel1'],
programms: state.programm.programms,
user: state.auth.user
}
}
const mapDispatchToProps = dispatch => bindActionCreators({
loadProgrammComponents,
loadProgramm
}, dispatch)
export default connect(
mapStateToProps,
mapDispatchToProps
)(ProgrammPage)
Комментарии:
1. Вы изменяете
programms[action.programmId]
вместо того, чтобы сохранять его неизменным. redux-react сравнит это значение, и, поскольку это одна и та же ссылка, оно сработает.
Ответ №1:
Вы возвращаете ту же ссылку.
Попробуйте вернуть копию programms
массива: [...programms]
(или Object.assign()
если это Object
).
case actionTypes.FETCH_PROGRAMM_COMPONENTS:
programms[action.programmId].components = action.payload;
console.log('Added Components')
return {
...state,
programms: [...programms] // <-- Return new state
}
Комментарии:
1. Спасибо, оператор распространения по какой-то причине не сработал, но
Object.assign
выполнил свою работу!