简体   繁体   中英

How to display fields from FieldArray in a different component (one component up) with redux-form

I use <FieldArray> from redux-form (slightly older version, react 16.3.0 and redux-form 7.2.1) and it works if I use it like in the docs. But I want the button to display in one component and the fields in a different component:

<App>
    <Cmp1/>
    <Cmp2/>
    // this is where I want the fields
</App>

The button should be in <Cmp1/> while the actual fields should be displayed in <App/> .

<App/> :

class App extends React.Component{
  constructor(props){
    this.state = {
      fields: []
    }
  } 
 
  onFieldArrayChange(field){
    const {fields} = this.state;
    const newFields = fields.push(field);
    this.setState({...this.state, fields: newFields});
  }

  render(){
     return (
       <div>
           My App 
           <div>{this.state.fields}</div>
           <Cmp1 onFieldArrayChange={this.onFieldArrayChange.bind(this)}
      </div>
     )

  }
}

I tried the following, <Cmp1/> :

class Cmp1 extends React.Component{
  renderMyFieldArray({ fields, meta: { error, submitFailed } }){
    return(
      <button type="button" onClick={() => this.props.onFieldArrayChange(<MyField
                      key={fields.length}
                      name={`myName[${fields.length}]`}
                      index={fields.length})
       >Add Field</button>
    ) 
  }
  
  render(){
    return(
      <FieldArray name="myName" component={this.renderMyFieldArray.bind(this} /> 
    )
  }
}

This works, however, the input is really slow. When I try to put in a string it cuts off after each letter and I have to click on the field again.

I also tried passing the fields up like so in <Cmp1/> :

<button type="button" onClick={() => this.props.onFieldArrayChange(fields)}>
     Add Filter
</button>

And in <App/> I set the state to the fields then:

onFieldArrayChange(field){
  const {fields} = this.state;
  const newFields = fields.push({});
  this.setState({...this.state, fields: newFields});
}

and then in the render function I map over the fields like so:

{this.state.fields.map((name, index)=>{
    return (
        <MyField
           key={index}
           name={name}
           index={index}
        />
    );
})}

In that case the first field does not get displayed. I have to click twice to get 1 field displayed.

How do I achieve this?

I couldn't really find a solution, but I solved it in a different way.

I put the <FieldArray name="myName" component={this.myRenderFunc.bind(this)} /> into <App/> with myRenderFunc:

myRenderFunc({ fields, meta: { error, submitFailed } }) {
        const handleClick = () => {
            fields.push({});
            this.setState({...this.state, fields});
        }

        return (
            <button type="button" onClick={handleClick.bind(this)}>
                Add Filter
            </button>
        );
    }

I save the fields in the state and then pass them down into my component:

<Comp1 fields={this.state.fields}/> .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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