Как сохранить извлеченные данные с сервера в состояние компонента, используя redux и redux-thunk?
В моем приложении реакции у меня есть компонент с именем profile, и я получаю данные с сервера и показываю их внутри этого компонента. Я использую Redux и Redux вместе с Axios. С помощью функции mapDispatchToProps я вызываю избыточное действие для извлечения этих данных, когда компонент смонтирован, и сохранения их в избыточном состоянии. После этого, используя функцию mapStateToProps, я показываю эти данные на экране с помощью реквизита. Это отлично работает. Теперь я хочу иметь возможность редактировать, например, имя этого пользователя. Для этого мне нужно сохранить эти данные в состояние компонента, когда данные извлекаются с сервера, а затем, когда текстовое поле изменяется, состояние компонента также необходимо изменить. Не знаю, как сохранить данные в компоненте сразу после загрузки.
Упрощенный код:
const mapStateToProps = (state) => {
return {
user: state.user
}
}
const mapDispatchToProps = (dispatch) => {
return {
getUserData: () => dispatch(userActions.getUserData())
}
}
class Profile extends Component {
state:{
user: {}
}
componentDidMount (){
this.props.getUserData()
// when data is saved to redux state i need to save it to component state
}
editTextField = () => {
this.setState({
[e.target.id]: e.target.value
})
};
render(){
const { user } = this.props;
return(
<TextField id="firstName"
value={user.firstName}
onChange={this.editTextField}
/>
)
}
}
2 ответа
Ты можешь использовать componentDidUpdate
для этого или дать функцию обратного вызова для вашего действия. Я покажу оба.
Сначала посмотрим componentDidUpdate
,
Здесь вы можете сравнить ваши предыдущие данные и ваши текущие данные, и, если есть некоторые изменения, вы можете установить свое состояние, например, если ваши данные являются массивом.
state = {
data: []
}
тогда внутри вашего componentDidUpdate
componentDidUpdate(prevProps, prevState) {
if(prevProps.data.length !== this.props.data.length) {
// update your state, in your case you just need userData, so you
// can compare something like name or something else, but still
// for better equality check, you can use lodash, it will also check for objects,
this.setState({ data: this.props.data});
}
}
_.isEqual(a, b); // returns false if different
Это было одно решение, другое решение - передать функцию обратного вызова вашему действию,
скажем, вы звоните this.props.getData()
вы можете сделать что-то вроде этого
this.props.getData((data) => {
this.setState({ data });
})
здесь вы передаете свои данные из избыточного действия в ваше состояние.
твое излишнее действие будет примерно таким.
export const getData = (done) => async dispatch => {
const data = await getSomeData(); // or api call
// when you dispatch your action, also call your done
done(data);
}
Если вы используете React 16.0+, вы можете использовать статический метод getDerivedStateFromProps
, Вы можете прочитать об этом реагировать документы.
Используя ваш пример:
class Profile extends Component {
// other methods here ...
static getDerivedStateFromProps(props) {
return {
user: props.user
}
}
// other methods here...
}