Home > Net >  ReactJS: the value in the input doesn't change when the state is update
ReactJS: the value in the input doesn't change when the state is update

Time:10-06

I try to implement a list of crop, and the user can modify the surface, the yield and the price of each crop. My initial state as a surface of 0, and a yield and a price that's been already define, the initial state look like that

C1 : ['Blé tendre', 0, 8.3, 191]
C2 : ["Orge d'hivers et escourgeon", 0, 6.75, 181]
C3 : ['Maïs grain', 0, 9.99, 178]
C4 : ['Soja', 0, 2.73, 379]

When the user types in the input of the surface, it is supposed to update the surface of the crop in the state and it did because the console.log of the state shows me this when I type 20 in the input of 'Blé tendre':

C1 : ['Blé tendre', 20, 8.3, 191]
C2 : ["Orge d'hivers et escourgeon", 0, 6.75, 181]
C3 : ['Maïs grain', 0, 9.99, 178]
C4 : ['Soja', 0, 2.73, 379]

I have the main file with the state in it:

Assolement.js

import React, { useState} from 'react';
import {Navigate} from 'react-router-dom'
import Entete from '../MEP/entete'
import Culture from './culture_assol'

function Assolement() {
  const [goToExploit, setGoToExploit] = useState(false)
  const [data, setData] = useState({"C1": ["Blé tendre", 0,8.3, 191], "C2": ["Orge d'hivers et escourgeon",0, 6.75, 181], "C3" :["Maïs grain",0, 9.99, 178], "C4": ["Soja",0, 2.73, 379]})

  const table_assol=  Object.keys(data).map(key => (
    <Culture 
    keys={key}
    data={data}
    MAJ_surf={MAJ_surf}
    libelle={data[key][0]}
    />
  ))

  function MAJ_surf(key,surf) {
    var newData= data;
    newData[key][1] = parseFloat(surf)//execute the manipulations
    setData(newData)
    setData(prev => {
      return prev;
    })
    console.log('surf')
    console.log(surf)
    console.log('data')
    console.log(data)
    console.log(data[key][1])    
  }

  function handleSubmit(event) {
    event.preventDefault()
    setGoToExploit(true)
  }

  if(goToExploit) {
    return <Navigate push to={`/exploitation`}/>
  }

  return (
    <div>
      <Entete titre="Assolement"/>
      <div className='container'>
        <h1>  </h1>
        <form onSubmit={handleSubmit}>
          <div className='table_assol'>
            {table_assol}
          </div>
          <div className='row'>
            <button type='submit' className='validation'> Enregistrer </button>
          </div>
        </form>
      </div>
    </div>
  );
}

export default Assolement;

And I have a culture_assol.js file that contains each crop (because at the end the list of crop is not gooing to be static and can move between 2 to 52 crops)

culture_assol.js

import React from 'react'

const Culture = ({keys,data, MAJ_surf, libelle}) => {
    function handleChangeSurface(event) {
        var surf = event.target.value;
        MAJ_surf(keys, surf);
        console.log(data)
        console.log(data[keys])
        console.log(data[keys][1])
    }

    return (
        <div className='row ligne_assol'>
            <div className='col_assol col_libelle'>
            {libelle}
            </div>
            <div className='col_assol col_surface'>
            <div className='videBlocAssol'>
                <input 
                className='input_assol'
                onChange={handleChangeSurface}
                value= {data[keys][1]}
                placeholder='0'
                type='text'/>
                <div className='pleinBlocAssol'>
                ha
                </div>
            </div>
            </div>
            <div className='col_assol col_rdt'>
            <div className='videBlocAssol'>
            <input 
                className='input_assol'
                value= {data[keys][2]}
                type='text'/>
                <div className='pleinBlocAssol'>
                t/ha
                </div>
            </div>
            </div>
            <div className='col_assol col_prix'>
            <div className='videBlocAssol'>
                <input 
                className='input_assol'
                value= {data[keys][3]}
                type='text'/>
                <div className='pleinBlocAssol'>
                €/t
                </div>
            </div>
            </div>
            <div className='col_assol col_PB_unitaire'>
            {Math.round(data[keys][2]*data[keys][3])} €
            </div>
            <div className='col_assol col_PB_tit_Prod'>
            {Math.round(data[keys][1]*data[keys][2]*data[keys][3])} €
            </div>
        </div>
    )
}
export default Culture;

Here is my code in a sandbox

I tried :

  • put the Maj_surf in the componen culure_assol,
  • without the setData(newData) setData(prev => {return prev;}) just with setData

Please if someone can help me or guide me to solve the problem

CodePudding user response:

The problem is that you are mutating the state which leads to no updates at all.

The problematic part is this

  function MAJ_surf(key, surf) {
    var newData = data;

You need to create a new object like this

  function MAJ_surf(key, surf) {
    var newData = {...data};

fixed sandbox

  • Related