CopyPastor

Detecting plagiarism made easy.

Score: 1; Reported for: Exact paragraph match Open both answers

Possible Plagiarism

Plagiarized on 2021-11-26
by Taha Janan Ismail

Original Post

Original - Posted on 2017-10-21
by Neurotransmitter



            
Present in both answers; Present only in the new answer; Present only in the old answer;

creat a state and u can use whatever method in the js code bellow
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const ParentComponent = () =>{ const [ShowChild,setShowChild]=useState(false) return( <div> //methode 1 {ShowChild && ChildComponent} // end methode 1 //methode 2 {ShowChild? <ChildComponent /> : ''} //end methode 2 <button onClick={()=>setShowChild(!ShowChild)}>show child Button </button> </div> )} const ChildComponent = () => { return( <h1>I m a child<h1> ) }
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<!-- end snippet -->

To modify deeply nested objects/variables in React's state, typically three methods are used: vanilla JavaScript's `Object.assign`, [immutability-helper][1] and `cloneDeep` from [Lodash][2]. There are also plenty of other less popular third-party libs to achieve this, but in this answer, I'll cover just these three options. Also, some additional vanilla JavaScript methods exist, like array spreading, (see @mpen's answer for example), but they are not very intuitive, easy to use and capable to handle all state manipulation situations. As was pointed innumerable times in top voted comments to the answers, whose authors propose a direct mutation of state: **just don't do that**. This is a ubiquitous React anti-pattern, which will inevitably lead to unwanted consequences. Learn the right way. Let's compare three widely used methods. Given this state object structure: state = { outer: { inner: 'initial value' } } You can use the following methods to update the inner-most `inner` field's value without affecting the rest of the state. # 1. __Vanilla JavaScript's Object.assign__ <!-- begin snippet: js hide: false console: true babel: true --> <!-- language: lang-js --> const App = () => { const [outer, setOuter] = React.useState({ inner: 'initial value' }) React.useEffect(() => { console.log('Before the shallow copying:', outer.inner) // initial value const newOuter = Object.assign({}, outer, { inner: 'updated value' }) console.log('After the shallow copy is taken, the value in the state is still:', outer.inner) // initial value setOuter(newOuter) }, []) console.log('In render:', outer.inner) return ( <section>Inner property: <i>{outer.inner}</i></section> ) } ReactDOM.render( <App />, document.getElementById('react') ) <!-- language: lang-html --> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.10.2/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.10.2/umd/react-dom.production.min.js"></script> <main id="react"></main> <!-- end snippet --> Keep in mind, that [Object.assign][3] **will not perform a deep cloning**, since [it only copies property values][4], and that's why what it does is called a *shallow copying* (see comments). For this to work, we should only manipulate the properties of [primitive][5] types (`outer.inner`), that is strings, numbers, booleans. In this example, we're creating a new constant (`const newOuter...`), using `Object.assign`, which creates an empty object (`{}`), copies `outer` object (`{ inner: 'initial value' }`) into it and then copies a different object `{ inner: 'updated value' }` **over** it. This way, in the end the newly created `newOuter` constant will hold a value of `{ inner: 'updated value' }` since the `inner` property got overridden. This `newOuter` is a brand new object, which is not linked to the object in state, so it can be mutated as needed and the state will stay the same and not changed until the command to update it is ran. The last part is to use `setOuter()` setter to replace the original `outer` in the state with a newly created `newOuter` object (only the value will change, the property name `outer` will not). Now imagine we have a more deep state like `state = { outer: { inner: { innerMost: 'initial value' } } }`. We could try to create the `newOuter` object and populate it with the `outer` contents from the state, but `Object.assign` will not be able to copy `innerMost`'s value to this newly created `newOuter` object since `innerMost` is nested too deeply. You could still copy `inner`, like in the example above, but since it's now an object and **not** a primitive, the **reference** from `newOuter.inner` will be copied to the `outer.inner` instead, which means that we will end up with local `newOuter` object directly tied to the object in the state. That means that in this case mutations of the locally created `newOuter.inner` will directly affect the `outer.inner` object (in state), since they are in fact became the same thing (in computer's memory). `Object.assign` therefore will only work if you have a relatively simple one level deep state structure with innermost members holding values of the primitive type. If you have deeper objects (2nd level or more), which you should update, don't use `Object.assign`. You risk mutating state directly. # 2. __Lodash's cloneDeep__ <!-- begin snippet: js hide: false console: true babel: true --> <!-- language: lang-js --> const App = () => { const [outer, setOuter] = React.useState({ inner: 'initial value' }) React.useEffect(() => { console.log('Before the deep cloning:', outer.inner) // initial value const newOuter = _.cloneDeep(outer) // cloneDeep() is coming from the Lodash lib newOuter.inner = 'updated value' console.log('After the deeply cloned object is modified, the value in the state is still:', outer.inner) // initial value setOuter(newOuter) }, []) console.log('In render:', outer.inner) return ( <section>Inner property: <i>{outer.inner}</i></section> ) } ReactDOM.render( <App />, document.getElementById('react') ) <!-- language: lang-html --> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.10.2/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.10.2/umd/react-dom.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script> <main id="react"></main> <!-- end snippet --> Lodash's [cloneDeep][6] is way more simple to use. It performs a *deep cloning*, so it is a robust option, if you have a fairly complex state with multi-level objects or arrays inside. Just `cloneDeep()` the top-level state property, mutate the cloned part in whatever way you please, and `setOuter()` it back to the state. # 3. __immutability-helper__ <!-- begin snippet: js hide: false console: true babel: true --> <!-- language: lang-js --> const App = () => { const [outer, setOuter] = React.useState({ inner: 'initial value' }) React.useEffect(() => { const update = immutabilityHelper console.log('Before the deep cloning and updating:', outer.inner) // initial value const newOuter = update(outer, { inner: { $set: 'updated value' } }) console.log('After the cloning and updating, the value in the state is still:', outer.inner) // initial value setOuter(newOuter) }, []) console.log('In render:', outer.inner) return ( <section>Inner property: <i>{outer.inner}</i></section> ) } ReactDOM.render( <App />, document.getElementById('react') ) <!-- language: lang-html --> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.10.2/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.10.2/umd/react-dom.production.min.js"></script> <script src="https://wzrd.in/standalone/immutability-helper@3.0.0"></script> <main id="react"></main> <!-- end snippet --> `immutability-helper` takes it to a whole new level, and the cool thing about it is that it can not only `$set` values to state items, but also `$push`, `$splice`, `$merge` (etc.) them. Here is a [list of commands][7] available. Side notes ========== Again, keep in mind, that `setOuter` only modifies the __first-level properties__ of the state object (`outer` in these examples), not the deeply nested (`outer.inner`). If it behaved in a different way, this question wouldn't exist. Which one is *right* for your project? -------------------------------------- If you don't want or can't use **external dependencies**, and have a **simple state structure**, stick to `Object.assign`. If you **manipulate a huge and/or complex state**, Lodash's `cloneDeep` is a wise choice. If you need **advanced capabilities**, i.e. if your state structure is complex and you need to perform all kinds of operations on it, try `immutability-helper`, it's a very advanced tool which can be used for state manipulation. ...or, do you ***really*** need to do this at all? ------------------------------------- If you hold a complex data in React's state, maybe this is a good time to think about other ways of handling it. Setting a complex state objects right in React components is not a straightforward operation, and I strongly suggest to think about different approaches. Most likely you better be off keeping your complex data in a Redux store, setting it there using reducers and/or sagas and access it using selectors. [1]: https://github.com/kolodny/immutability-helper [2]: https://lodash.com/ [3]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign [4]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Deep_Clone [5]: https://developer.mozilla.org/en-US/docs/Glossary/Primitive [6]: https://lodash.com/docs/#cloneDeep [7]: https://github.com/kolodny/immutability-helper#available-commands

        
Present in both answers; Present only in the new answer; Present only in the old answer;