0

I am trying to create a list of inputs using .map and storing the value of the individual inputs in an array. I can add the values to the array, but I can't get the value of the inputs to update from the array.

import React, { Component, useCallback, useState } from "react";
import {
    Card,
    Subheading,
    SkeletonBodyText,
    Layout,
    Page,
    Button,
    List,
    Heading,
    TextField
} from "@shopify/polaris";

export default function Index() {
    const [textFieldsList, setTextFieldsList] = useState([null]);

    const addTagCall = (value, index) => {
        let tester = textFieldsList;
        tester[index] = value;
        setTextFieldsList(tester);

        console.log(value + " index:" + index + " array" + textFieldsList);
    };

    return (
        <Page>
            <Heading>Test Page</Heading>

            <Layout>
                <Layout.Section>
                    {[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(i => (
                        <TextField
                            label={"Tag" + i}
                            onChange={newValue => addTagCall(newValue, i)}
                            value={textFieldsList[i]}
                        />
                    ))}
                </Layout.Section>
            </Layout>
        </Page>
    );
}

1 Answer 1

1

State should be immutable in react. Immutability in React

One way to update an item in array, is to "create" a new array, and using "map" loop over each of the items, and if the item's index has been found, use the new value instead.

  const [textFieldsList, setTextFieldsList] = useState([null,null,null,null,null,null,null,null,null,null]);

  const addTagCall = (value, index) => {
    setTextFieldsList((prevState) => {
       return prevState.map((prevValue, i) => index === i ? value : prevValue);
    });
    
    console.log(value+" index:"+index+" array"+textFieldsList);
  
  }

Another method, a bit more similiar to yours, using Object.assign:

  const addTagCall = (value, index) => {
    setTextFieldsList((prevState) => {
       return Object.assign([...prevState], {
         [index]: value
       });
    });
    
    console.log(value+" index:"+index+" array"+textFieldsList);
  }

Edit: With Method 1, you need to have all the values initialized.

So instead of:

... {[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(i => ( ...

you should have:

... {textFieldsList.map((value, i) => ( ...

PS: Also indexes start with 0, at the moment your i is actually your value variable starting with number 1, therefore when updating the first item, the 2nd item in the list would actually update.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. The first method did not work, the second one did. Thanks again
@Tiber , updated my answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.