Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update a "UseContext array" fail to re-render/generate a new component

Using context to store an array and try to array.map to generate a list of component, but the UI did not re-render to show all the component.

Program background:

I have a context which contain a array and the UI will have a "Add" button.

My Goal:

  1. when user press "Add"
  2. array in context will be pushed a new value in it
  3. UI will be rerender and generate a new component

My problem:

I have try to use useState to store the array and that is completely OK since, once I update the list using setArray, that will triggle re-render and display a new component.

However, when I try to use useContext, the page will not be rerendered.

  1. Should I still use useState to perform my goal? (then I have to manage 2 varible which are the context and state, I think that is a dummy way to work on it.)
  2. is there any other method to achievel my goal?

Here is the sandbox demo: https://codesandbox.io/s/falling-field-ur748?file=/src/App2.js

like image 960
0o0SkY0o0 Avatar asked Jan 26 '26 07:01

0o0SkY0o0


1 Answers

The component subscribing the context will re-render only when the value provided by the context changes.

Pushing the value to the list will not work here, because the reference of the list Array will not change when you push . So you should use the combination of state and context in this case .

Maintain the list in the state and pass it along with the state updater setList as the value to the Provider.

const [ list , setList ] = React.useState([121, 123])

  return (
    <UserContext.Provider value={[list, setList]}>
      <App2 />
    </UserContext.Provider>
  );

Now update the state from the component which subscribes the context .

export default function App2() {
  const [list, setList] = useContext(UserContext);
  const buttonOnClick = () => {
      setList(prevList => [...prevList, 321])
  };
  return (
    <>
      <button onClick={buttonOnClick}>Add</button>
      {list.map((item) => (
        <p>{item}</p>
      ))}
    </>
  );
}
like image 65
Shyam Avatar answered Jan 28 '26 21:01

Shyam



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!