我应该在哪里放置提供者redux?

时间:2020-06-09 17:04:04

标签: javascript reactjs redux antd

我是React的新手,我尝试进行JWT身份验证,但是我发现的教程和想要使用的新antd之间存在一些不兼容之处。如下所示的错误, 我试图添加一个提供程序,但是我可能没有正确放置它,请您能帮我吗?这是我的登录页面:

import React from 'react';
import { Form, Icon, Input, Button, Spin } from 'antd';
import { connect } from 'react-redux';
import { NavLink } from 'react-router-dom';
import * as actions from '../store/actions/auth';
import { Provider } from 'react-redux'

const antIcon = <Icon type="loading" style={{ fontSize: 24 }} spin />;

class NormalLoginForm extends React.Component {
  handleSubmit = (e) => {
    e.preventDefault();
    this.props.form.validateFields((err, values) => {
      if (!err) {
        this.props.onAuth(values.userName, values.password);
        this.props.history.push('/');
      }
    });
  }

  render() {
    let errorMessage = null;
    if (this.props.error) {
        errorMessage = (
            <p>{this.props.error.message}</p>
        );
    }

    const { getFieldDecorator } = this.props.form;
    return (

        <div>
            {errorMessage}
            {
                this.props.loading ?

                <Spin indicator={antIcon} />

                :
                <Form onSubmit={this.handleSubmit} className="login-form">
                    <Form.Item name='userName' rules={[{ required: true, message: 'Please input your username!' }]}>
                        <Input prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />} placeholder="Username" />
                    </Form.Item>

                    <Form.Item name="password" rules={[{ required: true, message: 'Please input your Password!' }]}>
                        <Input prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />} type="password" placeholder="Password" />
                    </Form.Item>

                    <Form.Item>
                    <Button type="primary" htmlType="submit" style={{marginRight: '10px'}}>
                        Login
                    </Button>
                    Or 
                    <NavLink 
                        style={{marginRight: '10px'}} 
                        to='/signup/'> signup
                    </NavLink>
                    </Form.Item>
                </Form>

            }
      </div>

    );
  }
}

function mapStateToProps(state) {
    return {
        loading: state.loading,
        error: state.error
    }
}

function mapDispatchToProps(dispatch){
    return {
        onAuth: (username, password) => dispatch(actions.authLogin(username, password)) 
    }
}

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

我运行它时,出现一些错误:

Error: Could not find "store" in the context of "Connect(NormalLoginForm)". Either wrap the root component in a <Provider>, or pass a custom React context provider to <Provider> and the corresponding React context consumer to Connect(NormalLoginForm) in connect options.

he above error occurred in the <ConnectFunction> component:
    in ConnectFunction (created by Context.Consumer)
    in Route (at routes.js:12)
    in div (at routes.js:9)
    in BaseRouter (at App.js:15)
    in div (at Layout.js:23)
    in main (created by Basic)
    in Basic (created by Context.Consumer)
    in Content (at Layout.js:17)
    in section (created by Context.Consumer)
    in BasicLayout (created by Context.Consumer)
    in Layout (at Layout.js:8)
    in CustomLayout (at App.js:14)
    in Router (created by BrowserRouter)
    in BrowserRouter (at App.js:13)
    in div (at App.js:12)
    in App (at src/index.js:7)

Consider adding an error boundary to your tree to customize error handling behavior.

还有一个警告:

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Check your code at Login.js:55.

2 个答案:

答案 0 :(得分:1)

我看到您正在导入{提供者},但我认为它没有被使用。您想要访问状态的任何组件都必须包装在该组件中。对于您的代码示例,请尝试以下操作:

return (
      <Provider>
        <div>
            {errorMessage}
            {
                this.props.loading ?

                <Spin indicator={antIcon} />

                :
                <Form onSubmit={this.handleSubmit} className="login-form">
                    <Form.Item name='userName' rules={[{ required: true, message: 'Please input your username!' }]}>
                        <Input prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />} placeholder="Username" />
                    </Form.Item>

                    <Form.Item name="password" rules={[{ required: true, message: 'Please input your Password!' }]}>
                        <Input prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />} type="password" placeholder="Password" />
                    </Form.Item>

                    <Form.Item>
                    <Button type="primary" htmlType="submit" style={{marginRight: '10px'}}>
                        Login
                    </Button>
                    Or 
                    <NavLink 
                        style={{marginRight: '10px'}} 
                        to='/signup/'> signup
                    </NavLink>
                    </Form.Item>
                </Form>

            }
      </div>
    <Provider />
    );

但是,这看起来像是应用程序的单个组件。假设您想要访问Redux存储库的组件更多,则最佳做法是将整个应用程序包装在顶级的Provider中。

答案 1 :(得分:0)

使用Redux提供程序包装您的整个应用程序。 您需要从redux导入您的商店; 并将您的商店设置为提供程序,并使用所有组件中的mapStateToProps获取商店数据。

return (
  <Provider store={store}>
    <div>
        {errorMessage}
        {
            this.props.loading ?

            <Spin indicator={antIcon} />

            :
            <Form onSubmit={this.handleSubmit} className="login-form">
                <Form.Item name='userName' rules={[{ required: true, message: 'Please input your username!' }]}>
                    <Input prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />} placeholder="Username" />
                </Form.Item>

                <Form.Item name="password" rules={[{ required: true, message: 'Please input your Password!' }]}>
                    <Input prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />} type="password" placeholder="Password" />
                </Form.Item>

                <Form.Item>
                <Button type="primary" htmlType="submit" style={{marginRight: '10px'}}>
                    Login
                </Button>
                Or 
                <NavLink 
                    style={{marginRight: '10px'}} 
                    to='/signup/'> signup
                </NavLink>
                </Form.Item>
            </Form>

        }
  </div>
<Provider />
);

提示:

  1. 您可以使用Redux useSelector 钩子代替mapStateToProps

  2. 和Redux UseDispatch 钩子,而不是mapDispatchToProps