Header Ads Widget

Ticker

6/recent/ticker-posts

Cómo pasar, acceder y actualizar el estado principal desde los componentes secundarios en React

 en un tutorial anterior , hemos creado una aplicación React simple con un Appcomponente principal un componente secundario ContactFormEl componente principal muestra una tabla HTML de datos que se recupera de un backend de la API de PHP y se almacena en una variable de estado denominada contactsEste es el ContactFormcomponente hijo de ejemplo :

class ContactForm extends React.Component {


    state = {
        name: '',
        email: '',
        country: '',
        city: '',
        job: '',

    }



    handleFormSubmit( event ) {
        event.preventDefault();


        let formData = new FormData();
        formData.append('name', this.state.name)
        formData.append('email', this.state.email)
        formData.append('city', this.state.city)
        formData.append('country', this.state.country)
        formData.append('job', this.state.job)

        axios({
            method: 'post',
            url: '/api/contacts.php',
            data: formData,
            config: { headers: {'Content-Type': 'multipart/form-data' }}
        })
        .then(function (response) {
            //handle success
            console.log(response)

        })
        .catch(function (response) {
            //handle error
            console.log(response)
        });
    }

    render(){
        return (
        <form>
            <label>Name</label>
            <input type="text" name="name" value={this.state.name}
                onChange={e => this.setState({ name: e.target.value })}/>

            <label>Email</label>
            <input type="email" name="email" value={this.state.email}
                onChange={e => this.setState({ email: e.target.value })}/>

            <label>Country</label>
            <input type="text" name="country" value={this.state.country}
                onChange={e => this.setState({ country: e.target.value })}/>

            <label>City</label>
            <input type="text" name="city" value={this.state.city}
                onChange={e => this.setState({ city: e.target.value })}/>

            <label>Job</label>
            <input type="text" name="job" value={this.state.job}
                onChange={e => this.setState({ job: e.target.value })}/>

            <input type="submit" onClick={e => this.handleFormSubmit(e)} value="Create Contact" />
        </form>);
    }
}

El componente secundario representa un formulario HTML y almacena su estado interno compuesto por los valores de los campos del formulario. También proporciona un handleFormSubmit()método que maneja el envío del formulario a la API REST de backend utilizando el cliente Axios y la FormDataestructura.

Esta es la implementación del Appcomponente principal :

class App extends React.Component {
  state = {
    contacts: []
  }

  componentDidMount() {
    const url = '/api/contacts.php'
    axios.get(url).then(response => response.data)
    .then((data) => {
      this.setState({ contacts: data })
      console.log(this.state.contacts)
     })
  }



  render() {
    return (
        <React.Fragment>
        <h1>Contact Management</h1>
        <table border='1' width='100%' >
        <tr>
            <th>Name</th>
            <th>Email</th>
            <th>Country</th>
            <th>City</th>
            <th>Job</th>     
        </tr>

        {this.state.contacts.map((contact) => (
        <tr>
            <td>{ contact.name }</td>
            <td>{ contact.email }</td>
            <td>{ contact.country }</td>
            <td>{ contact.city }</td>
            <td>{ contact.job }</td>
        </tr>
        ))}
        </table>
        <ContactForm />
        </React.Fragment>
    );
  }
}

El Appcomponente tiene una contactsvariable de estado que se utilizará para contener los datos recuperados de una API REST con Axios.

En el componentDidMount()método, enviamos una llamada a la API y usamos el método ReactsetState() para actualizar el estado del componente con los datos obtenidos.

El render()método devuelve un fragmento de React y muestra una tabla HTML de datos de contactos y el ContactFormcomponente.

ContactFormes un componente secundario de App.

Creamos nuevos contactos en el ContactFormcomponente y queremos que el nuevo contacto se agregue a la tabla HTML (es decir, al App contactsestado principal ) sin la necesidad de actualizar la tabla.

Esto significa que necesitamos acceder al contactsestado del Appcomponente principal desde el ContactFormcomponente secundario para poder enviar el nuevo contacto a la contactsmatriz en el handleFormSubmit()método del componente secundario cuando la Promesa de Axios se resuelve con éxito (es decir, el contacto se crea correctamente en el servidor ).

Cómo acceder al estado del componente principal desde el componente secundario en React

Podemos acceder al estado del componente principal de React usando varios métodos, como props y la API de contexto :

Envío del estado principal como accesorio de componente secundario

Puede enviar el estado del componente principal como apoyo al componente secundario:

<ContactForm contacts={this.state.contacts} />

En el componente principal, puede obtener el estado pasado de la siguiente manera:

 this.props.contacts

Dado que los accesorios son inmutables, no puede actualizar el estado principal con este método.

Uso de un método Prop para manejar la actualización del estado

Para poder acceder y actualizar el estado desde el componente hijo, podemos agregar un método que maneje la actualización del estado al componente padre y pasar el método como un accesorio al componente hijo en lugar del estado en sí.

Entonces, implementemos esto paso a paso en nuestro ejemplo anterior. En el Appcomponente principal , agregue el siguiente handleStateChange()método y vincúlelo a la clase:

class App extends React.Component {

  constructor () {
    super();
    this.handleStateChange = this.handleStateChange.bind(this);
  }

  state = {
    contacts: []
  }

  handleStateChange(value){
    event.preventDefault();
    let contacts = this.state.contacts;
    contacts.push(value);
    this.setState({ contacts : contacts })
  }

En el handleStateChange()método tomamos la contactsvariable de estado, presionamos el contacto pasado como parámetro y usamos el método ReactsetState() para actualizar el estado.

A continuación, pase el método como apoyo al componente secundario:

    <ContactForm handleStateChange = {this.handleStateChange} />

A continuación, llame al handleStateChange()método en el handleFormSubmit()método de ContactFormy pase el nuevo contacto como parámetro:

handleFormSubmit( event ) {
        event.preventDefault();


        let formData = new FormData();
        formData.append('name', this.state.name)
        formData.append('email', this.state.email)
        formData.append('city', this.state.city)
        formData.append('country', this.state.country)
        formData.append('job', this.state.job)

        var contact = {};
        formData.forEach(function(value, key){
            contact[key] = value;
        });
        this.props.handleStateChange(contact);

        /* [...] */
}

Utilice React Context API

Uso de Redux para acceder y actualizar el estado principal desde el componente secundario

Si su aplicación es más compleja que este simple ejemplo, puede usar una biblioteca de administración de estado como Redux y connect()los componentes AppContactFormen la contactstienda de Redux. En este caso, la contactsvariable de estado debe formar parte del estado global de la aplicación.

Conclusión

En este tutorial, hemos visto cómo acceder y actualizar el estado de un componente principal desde un componente secundario.

Publicar un comentario

0 Comentarios