React-redux如何在商店更新时更新组件道具

时间:2020-04-27 09:34:12

标签: reactjs react-redux

我认为,一旦商店更新,所有相关组件的道具也将被更新,但是prop(view)不会被更新。而且我不知道如何获取更新的数据。

这是我的测试代码,

userReducer.js

const initialState = null;
const userReducer = (state = initialState, action) => {
    switch (action.type) {
        case UPDATE_USER: {
            return Object.assign({}, action.user)
        }

        default:
            return state;
    }
};

export default userReducer;

(rootReducer)

export default combineReducers({
    user: userReducer,
});

userAction.js

export function login(email, password) {
    let user = {
        'email': email,
    };

    return {
        type: UPDATE_USER,
        user,
    }
}

App.js

class App extends Component {
    componentDidMount() {
        this.state = this.state || store.getState();
        console.log(this.state.user);
    }

    render() {
        return (
            <Provider store={store}>
                <Router>
                    <div className="App container">
                        {this.user
                            ? <Link to="/logout">Logout</Link>
                            : <Link to="/login">Login</Link>
                        }
                        <Switch>
                            <Route exact path="/" component={Home}/>
                            <Route path="/login" component={Login}/>
                            <Route render={() => <h2>Page not found.</h2>}/>
                        </Switch>
                    </div>
                </Router>
            </Provider>
        );
    }
}

export default App

Login.js

class登录扩展了组件{ 构造函数(道具){ 超级(道具); console.log(this.props.user); //输出:null }

postLogin = () => {
    let email = $('input[name="email"]').val();
    let password = $('input[name="password"]').val();

    this.props.dispatchLogin(email, password);

    console.log(this.props.user); // output: null

    // this.props.history.push('/');
};

render() {
    return (
        <div>
            <table>
                <tbody>
                <tr>
                    <th>email:</th>
                    <td><input type="text" name="email"/></td>
                </tr>
                <tr>
                    <th>password:</th>
                    <td><input type="password" name="password"/></td>
                </tr>
                </tbody>
            </table>
            <div>
                <button onClick={this.postLogin}>Login<

/button>
                </div>
            </div>
        );
    }
}

const mapStateToProps = (state) => ({
    user: state.user
});

const mapDispatchToProps = {
    dispatchLogin: (email, password) => login(email, password),
};

export default connect(mapStateToProps, mapDispatchToProps)(Login);

更改商店后,道具是否不会自动更新?如果是这样,我如何获得更新的值?登录后,我重定向到root(App.js)页面,但视图仍未更新。

1 个答案:

答案 0 :(得分:1)

我根据您的代码制作了一个存储库,您可以克隆该代码以查看工作示例。 https://github.com/cflynn07/sohelp-2020-04-27

您的主要问题在于您的App组件:

class App extends Component {
    componentDidMount() {
        this.state = this.state || store.getState();
        console.log(this.state.user);
    }

绝对不要直接从组件中分配或修改state,而应使用setState(如果不使用react-redux)或dispatch(如果使用react-redux)(此处关于为什么https://daveceddia.com/why-not-modify-react-state-directly/)的好文章

由于您正在使用react-redux,因此您希望通过组件的props获取状态数据。您可以使用react-redux的connect()方法将状态映射到道具(mapStateToProps),就像您已经在使用Login组件一样。

另外,不是从您的this.props.history.push('/')方法中调用postLogin(),而是通过react-router进行重定向的惯用方式是使用<Redirect组件。我在上面链接的仓库中的src/components/Login.js中提供了一个示例。

class Login extends Component {
  postLogin = () => {
    const email = $('input[name="email"]').val()
    const password = $('input[name="password"]').val()
    this.props.dispatchLogin(email, password)
  };

  render () {
    if (this.props.user) {
      return <Redirect to="/" />
    }
    return (
      <div>
        <table>
        ...