React redux不会更新mapStateToProps中的组件状态

时间:2018-01-20 19:10:49

标签: javascript react-native react-redux

我是新来的反应redux并且真的很难理解这里发生了什么。如果有人能够对这种情况有所了解,我将非常感激。

这是我的主屏幕:想的是,如果用户已经登录,那么我们会向他们显示此屏幕,否则我们会将其导航到登录屏幕。如果他们已登录,那么我们将从api获取所有信息并调用setUser操作。

const mapStateToProps = (state) => {
  return {
    user: state.userReducer[state.userReducer.length - 1],
  }
}

class HomeScreen extends React.Component {

  constructor(props) {
  super(props);
  this.state = {
    user: this.props.user
  };
}

  componentDidMount() {
    
      //Check if they've logged in already and set for redux.
      SecureStore.getItemAsync("USER_INFO").then(response => {
        if (response !== undefined && JSON.parse(response).id.length > 0) {
          fetch(WEB_API + '/api/getUserInfo/' + JSON.parse(response).id)
          .then(response => response.json())
          .then(responseJSON => {
            console.log("setting user");
            this.props.dispatch(setUser(responseJSON));
          })

        }
        else {
          const resetAction = NavigationActions.reset({
            index: 0,
            actions: [
              NavigationActions.navigate({ routeName: 'Login', params: this.props.navigation.state.params }),
            ]
          });
          this.props.navigation.dispatch(resetAction);
          //this.props.navigation.navigate('Login');
        }
      });
  }


  render() {
    //
  }

}

});

export default connect(mapStateToProps)(HomeScreen);

可以在这里找到setUser动作和reducer,它们在两个单独的文件中。

//UserReducer

const userReducer = (state = [], action) => {
  switch (action.type) {
    case 'SET_USER':
      return [
        ...state,
        {
          user: action.user
        }
      ]
    default:
      return state
  }
}

export default userReducer

//userAction

export const setUser = (user) => {
  return {
    type: 'SET_USER',
    user
  }
}

最后,在另一个组件中,我正在等待加载用户首选项的列表。因此,我需要等待来自redux的用户信息。所以在我的ComponentWillReceiveProps函数中,我有以下内容:

const mapStateToProps = (state) => {
  console.log(state);
  console.log("After mapping");
  return {
    user: state.userReducer[state.userReducer.length - 1],
  }
}

class LinksScreen extends React.Component {
  static navigationOptions = {
    title: 'Challenges',
  };

  componentDidMount() {

  }

  componentWillReceiveProps() {
    console.log("receiving");
    console.log(this.props);
    console.log(this.state);
    fetch(WEB_API + '/api/getAs/' + this.props.user.user.id)
     .then(response => response.json())
     .then(responseJSON => {
       this.setState({
         a: responseJSON
       })
     });
     fetch(WEB_API + '/api/getBs/' + this.props.user.user.id)
     .then(response => response.json())
     .then(responseJSON => {
       console.log(responseJSON);
       this.setState({
         b: responseJSON
       })
     });
  }

  constructor (props) {
    super(props);
    this.state = {
      user: this.props.user,
      challengesToVerify: [],
      challengesToDo: [],
    }
  }


  render() {
  }
}


export default connect(mapStateToProps)(LinksScreen);

我已经把console.logs放到了各处,但我觉得我要绕圈子,我只需要LinksScreen中的用户来获取A和B。 Redux杀了我!

1 个答案:

答案 0 :(得分:0)

如果您像这样编辑其他屏幕,我认为您的结构简单易读。

 const mapStateToProps = state => {
      const { user } = state.userReducer;
      return user;
    };

    class HomeScreen extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          user: this.props.user
        };
      }
      // Before component not render
      componentWillMount(){
        SecureStore.getItemAsync("USER_INFO").then(response => {
          if (response !== undefined && JSON.parse(response).id.length > 0) {
            this.props.getUserInfo(response);
          }
          else {
            const resetAction = NavigationActions.reset({
              index: 0,
              actions: [
                NavigationActions.navigate({ routeName: 'Login', params: this.props.navigation.state.params }),
              ]
            });
            this.props.navigation.dispatch(resetAction);
          }
        });
      }
      render() {
        // .....
      }
    }
    export default connect(mapStateToProps, { getUserInfo })(HomeScreen);


    // Action
    export const getUserInfo = (response) => dispatch => { // require redux-thunk for this dispatch
      fetch(WEB_API + '/api/getUserInfo/' + JSON.parse(response).id)
      .then(response => response.json())
      .then(responseJSON => {
        console.log("setting user");
        dispatch({
          type: 'GETUSERINFOSUCCESS',
          payload: { user: responseJSON}
        });
      })
    }


    // Reducer : userReducer

    const INITIAL_STATE = { 
      user: '',
    }

    export default (state = INITIAL_STATE, action) => {
      switch (action.type) {
        case "GETUSERINFOSUCCESS":
          return { ...state, user: action.payload.user };
        default:
          return state;
      }
    };