RisingStack / react-easy-state

Simple React state management. Made with ❤️ and ES6 Proxies.
MIT License
2.56k stars 104 forks source link

State not updating inside Formik render function #220

Open levani opened 4 years ago

levani commented 4 years ago

React Easy State version: 6.3.0 Platform: browser / react-native

Describe the bug When I'm displaying a state inside Formik render function, if the state is updated the component is not re-rendering properly. For some reason I have to trigger the update second time to cause the re-render.

Here is a working example: https://codesandbox.io/s/compassionate-https-0jlp6?file=/src/App.js

You will have to click the submit button twice to change the text from "false" to "true".


For tougher bugs

To Reproduce

Expected behavior The text next to the button should become "true" after one click.


For the toughest bugs only

CodeSandbox reproduction https://codesandbox.io/s/compassionate-https-0jlp6?file=/src/App.js

michalczaplinski commented 3 years ago

This would be because the Formik component does not know that it should re-render when user.isLoggedIn changes.

You can fix it by wrapping Formik with view: https://codesandbox.io/s/epic-breeze-plvis?file=/src/App.js

Also, related to this point, if you've using third-party components you might want to check the Passing nested data to third party components. section of the README.md:

Third party helpers - like data grids - may consist of many internal components which can not be wrapped by view, but sometimes you would like them to re-render when the passed data mutates. Traditional React components re-render when their props change by reference, so mutating the passed reactive data won't work in these cases. You can solve this issue by deep cloning the observable data before passing it to the component. This creates a new reference for the consuming component on every store mutation.

import React from 'react'; import { view, store } from '@risingstack/react-easy-state'; import Table from 'rc-table'; import cloneDeep from 'lodash/cloneDeep';

const dataStore = store({ items: [ { product: 'Car', value: 12, }, ], });

export default view(() => (

));