我在react-redux-firebase项目中将一个类组件重写为一个功能组件



我正在重建这个组件。https://github.com/ayush221b/MarioPlan-react-redux-firebase-app/blob/master/src/Components/projects/CreateProject.js

https://github.com/ayush221b/MarioPlan-react-redux-firebase-app/blob/master/src/store/actions/projectActions.js

然而,我不知道如何重写mapStateToProps和mapDispatchToProps

错误提示

FirebaseError:函数addDoc()调用无效数据。文档字段不能为空(在文档项目/5to35LFKROA5aKMXpjqy字段' '中找到)

项目似乎没有被调度??

import  {Component ,useState}  from 'react'
import  {connect} from 'react-redux'
import  {createProject} from '../../store/actions/projectActions'
import { useForm } from "react-hook-form";
import { Redirect } from 'react-router-dom'

const CreateProject = (props) => {
const [state, setState] = useState({
title: "",
content: ""
});
const handleChange = event => {
setState({ ...state, [event.target.name]: event.target.value });
};

const handleSubmit = (e) => {
e.preventDefault();
console.log(state);
props.createProject(state);
props.history.push('/');
}
const { auth } = props;
return (
<div className="container">
<form className="white" onSubmit={handleSubmit}>
<h5 className="grey-text text-darken-3">Create a New Project</h5>
<div className="input-field">
<input type="text" id='title' onChange={handleChange} />
<label htmlFor="title">Project Title</label>
</div>
<div className="input-field">
<textarea id="content" className="materialize-textarea" onChange={handleChange}></textarea>
<label htmlFor="content">Project Content</label>
</div>
<div className="input-field">
<button className="btn pink lighten-1">Create</button>
</div>
</form>
</div>
)
}
const mapDispatchToProps = (dispatch) => {
console.log("a"+dispatch);
return {
createProject: (project) => dispatch(createProject(project))
}
}
const mapStateToProps = (state) =>{
return{
auth: state.firebase.auth
}
}

export default connect(mapStateToProps,mapDispatchToProps)(CreateProject)

在函数组件中,你可以使用"useSelector"获取存储状态

const firebase = useSelector(state => state.firebase) 

和"useDispatch"触发一个动作

const dispatch = useDispatch()

<button  onClick={() => dispatch({ type: 'GET_DATA' })} >Click me</button>

不要忘记导入

import { useSelector, useDispatch } from 'react-redux'

问题:输入上缺少name属性

FirebaseError:函数addDoc()调用无效数据。文档字段不能为空(在文档项目/5to35LFKROA5aKMXpjqy字段' '中找到)

这个错误与mapStateToProps没有任何关系。您传递了一个带有空键的对象,将导致测试失败。

{
title: "Some Title", 
content: "some content",
'': "some value"
}

那么空键是从哪里来的呢?好吧,你正在使用基于event.target.name的动态密钥设置状态值。

const handleChange = (event) => {
setState({
...state, 
[event.target.name]: event.target.value
});
};

当你改变inputtextarea时,event.target.name是什么?看一下你的代码。

<input type="text" id="title" onChange={handleChange} />

没有name属性!

你必须:A)在每个输入中添加一个name,对应于你想要更新的state中的属性。

<input type="text" id="title" name="title" onChange={handleChange} />

或B)更改您的setState使用event.target.id,这是已经设置的。

const handleChange = (event) => {
setState({
...state,
[event.target.id]: event.target.value
});
};

我推荐B),因为看起来你以前就是这么做的。

回来的钩子与redux钩子集成非常简单。在我看来,比处理connect更容易。

从选择器访问auth

const auth = useSelector((state) => state.firebase.auth);

调用useDispatch,添加组件的顶层以访问dispatch

const dispatch = useDispatch();

在你的handleSubmit中,调用dispatch和你的行动创建者的结果。

dispatch(createProject(state));

完整代码

const CreateProject = (props) => {
const auth = useSelector((state) => state.firebase.auth);
const dispatch = useDispatch();
const [state, setState] = useState({
title: "",
content: ""
});
const handleChange = (event) => {
setState({ ...state, [event.target.id]: event.target.value });
};
const handleSubmit = (e) => {
e.preventDefault();
console.log(state);
dispatch(createProject(state));
props.history.push("/");
};
return (
<div className="container">
<form className="white" onSubmit={handleSubmit}>
<h5 className="grey-text text-darken-3">Create a New Project</h5>
<div className="input-field">
<input type="text" id="title" onChange={handleChange} />
<label htmlFor="title">Project Title</label>
</div>
<div className="input-field">
<textarea
id="content"
className="materialize-textarea"
onChange={handleChange}
/>
<label htmlFor="content">Project Content</label>
</div>
<div className="input-field">
<button className="btn pink lighten-1">Create</button>
</div>
</form>
</div>
);
};

相关内容

  • 没有找到相关文章

最新更新