Как сохранить извлеченные данные с сервера в состояние компонента, используя 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...
}
Другие вопросы по тегам