Tengo 4 componentes de reacción, llamados A, B, C y D. A es el componente principal, B, C y D es el componente secundario que se coloca en el componente A. Cada componente produciría datos (entrada del usuario), pero el botón de envío / acción colocada en el componente principal (componente A). Luego, todos los datos de todos los componentes se enviarán a una API, llamada http: // localhost: 8000 / create_data . Lo envío a una API porque primero quiero procesar todos los datos y luego ingresarlos en mi base de datos.

1er enfoque: el botón enviar es un evento onClick que hace setState en componentA

state = {
    instruction: 'not submit'
}

instruction = () => {
    this.setState({
        instruction: 'submit'
    })
}

<componentB instruction={this.state.instruction}/>
<componentC instruction={this.state.instruction}/>
<componentD instruction={this.state.instruction}/>
<Button type="button" color="primary" onClick={this.instruction}>Submit</Button>

Luego, en cada componente hijo, creo componentWillReceiveProps (), se ve así:

componentWillReceiveProps = (val) => {
    const messages = 'this is from componentB';
    if (val.instruction === 'submit') {
        axios.post('http://localhost:8000/create_data', {
            value: messages
        })
    }
}

En el servidor,

app.post('/create_data', (req, res) => {
    console.log(req.body.value)
    // this single console log print three value:
    // this is from componentB
    // this is from componentC
    // this is from componentD
    // I dont know how to separate them
})

Segundo enfoque: traté de pasar uno más accesorios a cada niño, que es una función. Entonces, cuando this.state.instruction cambia a 'submit', llamo a la función props y le paso el valor del niño al padre. Obtuve el valor, pero luego, cómo supongo que lo enviaré a una API ya que paso tres funciones diferentes como accesorios para cada componente.

¿Alguna otra forma mejor de lograrlo? gracias por adelantado

1
Akza 17 oct. 2018 a las 06:34

2 respuestas

La mejor respuesta

Lo está haciendo todo mal, a continuación se muestra una mejor manera de implementar lo que está tratando de lograr;

class A extends Component {

   state = {
       messages: {
          b:'',
          c:'',
          d: ''
        }
     }

    handleSubmit = () => {
        const { messages } = this.state
        // you could check if messages is not empty before sending
        axios.post('http://localhost:8000/create_data', {
        value: messages
       })
     }

    handleMessageChange = (name, message) => {
       // perform validations on message before adding it to state
       const {messages} = this.state
       this.setState({messages: {...messages, [name]:message}})
     }

  render(){
    const {messages} = this.state
    const b='b'
    const c='c'
    const d='d'
    return(
       <div>
        <componentB 
          message={message[b]} 
          name={b} 
          onChange={this.handleMessageChange}
         />
        <componentC 
          message={message[c]} 
          name={c} 
          onChange={this.handleMessageChange}
         />
        <componentD 
          message={message[d]} 
          name={d} 
          onChange={this.handleMessageChange}
         />

         <Button 
           type="button" 
           color="primary" 
           onClick={this.handleSubmit}>
           Submit
         </Button>
       </div>
       )
      }

Y sus componentes B, C y D deberían verse así a continuación;

      class ComponentD extends {

         handleChange = (event) => {

             const {name, value} = event.target
             this.props.onChange(name, value)
           }

          render() {
            const {message, name} = this.props
            return(
               <input 
                 name={name} 
                 value={message} 
                 onChange={this.handleChange}
               />
            )
           }
         }

Si un componente secundario tiene varias entradas, puede hacer lo siguiente

Child component EF

      class ComponentEF extends {

     handleChange = (event) => {

         const {name, value} = event.target
         this.props.onChange(name, value)
       }

      render() {
        const {messages:{e,f}} = this.props
        return(
          <React.Fragment>
           <input 
             name="e" 
             value={e} 
             onChange={this.handleChange}
           />
           <input 
             name="f" 
             value={f} 
             onChange={this.handleChange}
           />
         </React.Fragment>
        )
       }
     }

In the parent component

  render(){
     const {messages:{b,c,d,...rest}} = this.state
    return(
        <div>
          <componentB 
            message={b} 
            name={"b"} 
            onChange={this.handleMessageChange}
          />
         <componentC 
            message={c} 
            name={"c"} 
            onChange={this.handleMessageChange}
         />
         <componentD 
            message={d} 
            name={"d"} 
            onChange={this.handleMessageChange}
         />
          <componentEF
            messages={rest} 
            onChange={this.handleMessageChange}
         />

         <Button 
           type="button" 
           color="primary" 
           onClick={this.handleSubmit}>
            Submit
         </Button>
   </div>
   )
  }
1
Rex Ogbemudia 18 oct. 2018 a las 06:20

Lo más probable es que se trate de un problema de encuadernación. Prueba <Button type="button" color="primary" onClick={this.instruction.bind(this)}>Submit</Button>

0
Sarah Hailey 17 oct. 2018 a las 03:40