首页 > 解决方案 > 如何使用 redux 和 redux-thunk 将获取的数据从服务器保存到组件状态?

问题描述

在我的反应应用程序中,我有一个名为配置文件的组件,我正在从服务器获取数据并将其显示在该组件中。我正在使用 redux 和 redux-thunk 以及 axios。在 mapDispatchToProps 函数的帮助下,我正在调用 redux 操作以在安装组件时获取该数据并将其保存到 redux 状态。之后,使用 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}
            />
        )

    }
}

标签: reactjsreduxreact-reduxreact-propsreact-state

解决方案


您可以为此使用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 });
})

在这里,您将数据从 redux 操作传递到您的状态。

您的 redux 操作将是这样的。

export const getData = (done) => async dispatch => {
  const data = await getSomeData(); // or api call

  // when you dispatch your action, also call your done 
  done(data);
}

推荐阅读