0

In this Code Sandbox, I have a provider that initializes and passes context to App

const appContext = {
  person: "Larry"
};

render(
  <BrowserRouter>
    <AppContext.Provider value={appContext}>
      <App />
    </AppContext.Provider>
  </BrowserRouter>,
  document.getElementById("root")
);

And there's a consumer under App that modifies context depending on its state. It does this so when a user clicks into a different link and comes back, the state (in this case, the selected dropdown) can be restored from context.

const Consumer = props => {
  const [dropdownOpen, setOpen] = useState(false);
  const appContext = useContext(AppContext);

  const toggle = () => setOpen(!dropdownOpen);
  const changePerson = e => {
    appContext.person = e.currentTarget.textContent;
  };
  const people = ["Moe", "Larry", "Curly"];
  return (
    <ButtonDropdown isOpen={dropdownOpen} toggle={toggle}>
      <DropdownToggle caret>{appContext.person}</DropdownToggle>
      <DropdownMenu>
        {people.map((p, idx) => {
          return (
            <DropdownItem
              key={idx}
              active={appContext.person === p}
              onClick={changePerson}
            >
              {p}
            </DropdownItem>
          );
        })}
      </DropdownMenu>
    </ButtonDropdown>
  );
};

Is it safe to directly update appContext.person in the consumer as shown above? The code runs fine, but I just want to make sure it's ok to do this.

Ravi
  • 3,718
  • 7
  • 39
  • 57
  • 2
    I'd recommend against doing this. It will probably work fine in simple situations where the context is being directly consumed by few components, but it runs the risk of having data that's out of sync, and potentially not triggering actions that are listening to a change in that value to run. The [docs](https://reactjs.org/docs/context.html#updating-context-from-a-nested-component) recommend storing your mutable data in state and then passing down a function that can be used to update the values. The example there uses class components but it's the same concept. – Chris B. Jan 30 '20 at 20:36
  • I agree with @ChrisB. Take a look at [how to change context value while using react usecontext](https://stackoverflow.com/questions/54738681/how-to-change-context-value-while-using-react-hook-of-usecontext) – awran5 Jan 30 '20 at 20:41
  • Thanks for both examples, I'll revise my code to follow that pattern. – Ravi Jan 31 '20 at 02:48

0 Answers0