我是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.
答案 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 />
);
提示:
您可以使用Redux useSelector 钩子代替mapStateToProps
和Redux UseDispatch 钩子,而不是mapDispatchToProps