Lor*_*nzo 6 javascript reactjs
我正在尝试在 React 中创建一个 Form 组件,有点像Formik,但更简单。
我的想法是onChange为所有孩子添加一个处理程序。我正在这样做children.map()。它有效,但是我收到一个关键警告
Warning: Each child in a list should have a unique "key" prop.
Run Code Online (Sandbox Code Playgroud)
我知道没有办法抑制这种情况,所以也许有更好的方法来创建这个表单组件?<input>另外,如果不是直系孩子,我应该如何处理这种情况?
编辑:我知道如何避免这个问题,我主要想要解决这个问题的最佳方法,包括嵌套输入的情况。
这是我想如何使用它:
<Form>
<label htmlFor="owner">Owner</label>
<input
type="text"
name="owner"
id="owner"
/>
<label htmlFor="description">Description</label>
<input
type="text"
name="description"
id="description"
/>
<input
type="submit"
value="Submit"
/>
</Form>
Run Code Online (Sandbox Code Playgroud)
这是我的代码:
import React from 'react';
class Form extends React.Component {
constructor(props) {
super(props);
this.state = {}
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value =
target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
console.log(`${name} : ${value}`)
this.setState({
[name]: value
});
}
render() {
return (
<form>
{this.props.children.map((child) => {
if (child.type === "input") {
return (
<input
onChange={this.handleInputChange}
{...child.props}
/>
)
}
})}
</form>
)
}
}
export default Form;
Run Code Online (Sandbox Code Playgroud)
如果您使用渲染道具,则根本不会遇到unique "key"道具问题(这也是 Formik 的实现方式)。
您的组件可以很容易地设置为handleChange作为渲染道具传递给其子组件,并且这也不需要您将其作为input直接子组件。
class Form extends Component {\n ...\n handleInputChange() {...}\n\n render() {\n // Note that we call children as a function,\n // passing `handleChangeInput` as the argument.\n // If you want to pass other other things to the\n // children (handleSubmit, values from state), just\n // add them to the argument you\'re passing in.\n this.props.children({this.handleInputChange});\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n使用方法如下:
\n\n<Form>\n // Notice that <Form> needs its immediate child to be\n // a function, which has your handler as the argument:\n {({handeInputChange}) => {\n return (\n <form>\n <input type="text" name="owner" onChange={handleInputChange} />\n <input type="checkbox" name="toggle" onChange={handleInputChange} />\n <div>\n // inputs can be nested in other elements\n <input name=\xe2\x80\x9cinner\xe2\x80\x9d onChange={handleInputChange} />\n <div>\n <form>\n ) \n }}\n</Form>\nRun Code Online (Sandbox Code Playgroud)\n\n编辑:您在评论中提到您不想将处理程序显式传递给每个输入。实现此目的的另一种方法是使用 React Context,在表单中使用 Provider,并将每个 Providerinput包装在一个 Consumer 中:
const FormContext = React.createContext();\n\nconst FormInput = (props) => {\n const {handleInputChange} = useContext(FormContext);\n return <input handleInputChange={handleInputChange} {...props} />\n}\n\nclass Form extends Component {\n ...\n handleInputChange() {...}\n\n render() {\n // Pass anything you want into `value` (state, other handlers),\n // it will be accessible in the consumer \n <Provider value={{ handleInputChange: this.handleInputChange }}>\n <form>\n {this.props.children}\n </form>\n </Provider>\n }\n}\n\n// Usage:\n<Form>\n <FormInput type="text" name="owner" />\n <FormInput type="submit" name="submit" />\n <div>\n <FormInput type="checkbox" name="toggle" />\n </div>\n</Form>\nRun Code Online (Sandbox Code Playgroud)\n\n事实上,Formik 也有这个选项,无论是Field组件还是connect功能。
| 归档时间: |
|
| 查看次数: |
5275 次 |
| 最近记录: |