Home > Back-end >  How to store state on each state update in React
How to store state on each state update in React

Time:02-24

Say I have a parent component that renders multiple child components based on an array using .map() method. Using some inputs child component then creates an object which it returns with a callback function on state update.

const InputRows = () => {

    const [incomeObj, setIncomeObj] = useState({});

    const fruits= ['apple' , 'orange', 'banana', 'pineapple'];
    
    return (
            fruits.map((fruit, index)=>
                    <tr key={index}>
                        <InputRow fruit={fruit} number={index} setIncomeObj={setIncomeObj}/>
                    </tr>
           )

What I need to do now is to store returned objects from all the child components inside one object to then send it out as JSON.

I've tried multiple ways to do it, for example something like using useEffect hook:

let combinedIncomeObj = {};

useEffect(() => {
    Object.assign(combinedIncomeObj, incomeObj);
    console.log(combinedIncomeObj);
  }, [incomeObj]);

But of course it just replaces existing data in combinedIncomeObj on each state update, not adding to it. Is using state managers like Redux is the only way to achieve my goal? Or am I just missing something?

CodePudding user response:

Why not have a dedicated function for this?
You could try this:

const InputRows = () => {

    const [incomeObj, setIncomeObj] = useState({});

    const fruits= ['apple' , 'orange', 'banana', 'pineapple'];

    const onUpdateIncomeObj = (newIncomeObj) => {
       setIncomeObj({
          ...incomeObj,
          newIncomeObj,
       })
    }
    
    return (
        fruits.map((fruit, index)=>
           <tr key={index}>
               <InputRow
                  fruit={fruit} 
                  number={index}
                  setIncomeObj={onUpdateIncomeObj}
               />
           </tr>
        )

Alternatively, if you want to avoid this, you can send adjust the setIncomeObj function you pass right in the prop, like this:

return (
   fruits.map((fruit, index)=>
       <tr key={index}>
         <InputRow 
            fruit={fruit} 
            number={index}
            setIncomeObj={(newIncomeObj) => setIncomeObj({
                ...incomeObj,
                newIncomeObj,
            })/>
       </tr>

CodePudding user response:

Send the data as array of objects like this [{ } , { } ] Just follow the below code

const InputRows = () => {

    const [incomeObj, setIncomeObj] = useState([]);

    const fruits= ['apple' , 'orange', 'banana', 'pineapple'];
    const handleIncomeObj = (obj)=>{
      setIncomeObj([...incomeObj,{...obj} ]);
    }
    
    return (
            fruits.map((fruit, index)=>
                    <tr key={index}>
                        <InputRow fruit={fruit} number={index} setIncomeObj={obj=>hanleIncomeObj(obj)}/>
                    </tr>
           )

I hope you find it helpful .

CodePudding user response:

if you want to add to the object you can use spread syntax

let combinedIncomeObj = {};

useEffect(() => {
    combinedIncomeObj = {...combinedIncomeObj, incomeObj}
    console.log(combinedIncomeObj);
  }, [incomeObj]);
  • Related