简体   繁体   English

React.js向子组件添加组件

[英]React.js adding component to child

import FieldSect from "./fieldSect.js" 
<div>
  <FieldSect />
</div>

--FieldSect.js-- --FieldSect.js--

import Field from "./Field.js"
<div>
   <Field />
<button onclick={addField}> addField </field>
</div>

--Field.js-- --Field.js--

function Field (){
    <div>
      <label> Test </label>
      <input type="text" />
    </div>

} }

My code works in the part where Field is loaded immediately and is shown correctly. 我的代码在立即加载Field并正确显示的部分起作用。 I am really struggling on trying to figure out how to keep adding the <Field /> component under the already existing <Field /> whenever the add button is clicked. 我真的很想尝试找出如何在单击添加按钮时继续在现有的<Field />下添加<Field />组件。 I also need to ensure to have the ability to keep adding rather than having a specific number of available 我还需要确保具有不断添加而不是具有特定数量的可用功能的能力

I also cannot use the DOM as I am getting an error telling me to edit the state rather than using DOM.render 我也无法使用DOM,因为出现错误提示我编辑状态而不是使用DOM.render

End Result should look something like this: --FieldSect.js-- 最终结果应如下所示:--FieldSect.js--

<div>
   <Field />
   ...<Field /> (Button Add Click)
   ...<Field /> (Button Add Click)
   ..
</div>

You should have Fields be part of the state of your parent component, perhaps as an array, this.state = {fields:[{id:1},{id:2},{id:3}]} . 您应该让Fields成为父组件状态的一部分,或者作为数组this.state = {fields:[{id:1},{id:2},{id:3}]}

Then, when rendering, you can iterate over the array: 然后,在渲染时,可以遍历数组:

<div>
   {this.state.fields.map(f => <Field key={f.id}/>)}
</div>

Its super simple. 它超级简单。

Have a default state of fields for example lets say that you want to have 1 field at the beginning 拥有默认的字段状态,例如,假设您想在开头添加1个字段

this.state = {
 fields: [<Field/>]
}

Now use onClick event for AddClick and a function as follows 现在将onClick事件用于AddClick和一个函数,如下所示

handleOnClick=(event)=>this.setState(prevState=>({...prevState, fields: [...prevState.fields, <Field/>]})

And in your render function iterate over fields array 并在您的渲染函数中遍历fields array

PS: I am not sure what is a Field doing. PS:我不确定Field在做什么。

What I would do is in render 我会做的是渲染

<div>
   {this.state.fields.map(field => <Field {...field}/>)}
</div>

and fields would be the data of a field 并且字段将是字段的数据

If I'm understanding you correctly, you're wanting to add a every time someone clicks a button. 如果我对您的理解正确,那么您希望每次有人单击按钮时添加一个。 If that's accurate, then I would simply add a constructor with a state to either the FieldSect.js or parent file to that (somewhere along the line before Field.js) that creates a trackable state. 如果这是正确的,那么我只需向FieldSect.js或父文件(在Field.js之前的某处)添加一个具有状态的构造函数,以创建可跟踪状态。 Something like: 就像是:

this.state = {
        NumberOfFields: 1
    };

If you do this ahead of FieldSect.js, then it needs to be passed down in props. 如果在FieldSect.js之前执行此操作,则需要将其传递给props。

Now you need to set up the onClick function to increment this state. 现在,您需要设置onClick函数以增加此状态。 Using this, you can then create a loop in FieldSect.js that creates an array of elements that will be rendered in React. 然后,您可以使用它在FieldSect.js中创建一个循环,该循环创建将在React中呈现的元素数组。

let array = []
for(let i = 0; i < this.NumberOfFields; i++){
  array.push(<Field key={Math.random()}/>)
}

Then, instead of using in FieldSect.js, use {array}. 然后,使用{array}而不是在FieldSect.js中使用。

The reason I added the key attribute to the Field is that all elements that are derived from an iteration like this must have a unique key. 我将key属性添加到Field的原因是,从这样的迭代派生的所有元素都必须具有唯一的键。

Here you go. 干得好。

This holds the number of <Fields /> in the state of a controlled component, which can be incremented with the button. 这将保持受控组件状态下的<Fields />数量,可以通过按钮增加该数量。

The loop is generated by creating an Array of nbrOfFields length, destructured, and then mapped over. 通过创建长度为nbrOfFields的数组, nbrOfFields解构,然后映射在上面来生成循环。

 const Field = () => ( <div> <label> Test </label> <input type="text" /> </div> ); class App extends React.Component { constructor() { super(); this.state = {nbrOfFields: 1}; this.addField = this.addField.bind(this); } addField() { this.setState(prevState => ({nbrOfFields: prevState.nbrOfFields + 1})); } render() { return ( <div> {[...Array(this.state.nbrOfFields)].map((item, i) => ( <Field key={i} /> ))} <button onClick={this.addField}>Add field</button> </div> ); } } ReactDOM.render(<App />, document.getElementById("app")); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div id="app"></div> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM