I've managed to add React elements dynamically depending on the content height Add React elements dynamically depending on the content height
I've prepared a codesandbox to show this:
https://codesandbox.io/s/html-react-parser-forked-8pl3b
However, the problem I'm having right know is that the child component, which shows the actual article, is not reacting to the state updated of its parent. This can be tested just by clicking on the Article 2 button.
Is it related to the usage of the reference? I can't figure out what is happening.
It's because the Article component has its own state. The html prop you pass in const [article, setArticle] = React.useState(parse(html)); is the initial value and it's ignored when the prop changes.
You can use the useEffect hook to update the state when the prop's changed. You will also need to reset the didInsertAds state:
React.useEffect(() => {
setArticle(parse(html));
setDidInsertAds(false);
}, [html]);
Related
I have a parent component that holds a string as a state. This string is composed with help from other child components.
Then the parent sends this string to a DisplayText component that displays it. However in the DisplayText component there is an internal state for that string and thus the user can change it however they like, and the result
const [myString, setMyString] = React.useState<string>('');
React.useEffect(() => {
// do some stuff with the string and save it
setMyString(string);
}, [...]);
<Textarea
value={myString}
onChange={(value) => setMyString(value)}
/>
(This is just basic React.) I would like to add a button in the parent component that forces the child to override any changes the user has made, and re-render the text coming from the parent. This happens naturally when the state in the parent changes, but how can you simulate the same effect when a button in the parent is clicked?
I could solve this by moving the internal state of editing the text from the child to the parent, so clicking the button can control that, but is there another way without doing so? Because the edited text shouldn't concern the parent. The second solution I thought of would be to force a re-render of the parent but the ways to do so are hacky (changing a dummy state).
Is there a simple solution to this?
Composing a string in multiple child components seems like a bad approach to me. But if you really need or want to do it that way, then adding a button in the partent component, that overwrites myString, should work. The props that refer to this value will update automatically. Just remove the internal state of the children, to have a 'single source of truth'.
That sounds like bad practice to me.
You should:
lift state up to parent and have a default value which is saved. Clicking the button should just reset to the default value.
If you need to change the parent state from one or more childs, you should pass down a setter function which sets the state in the parent.
This question is related to this one. I am rewording to make it simple.
I have a main navigation component (MainNavigation.js) which is siblings with a Secondary Navigation Component(SecNavigation.js) under the Header component(Header.js).
What I want is when I click on a specific Link in the MainNavigation.js the whole SecNavigation.js to be displayed in a modal.
My problem here is that I don't quite grasp how should I go using useState, useContext or even if I need any of this.
Hope this will clear something for you
What you need is a parent that handles the state and then it will pass it down to its children. Because the parent is keeping track of the children and what they are doing.
So what I have done it this:
App.js is the parent and I handle the state here.
Then I just pass down the setIsModalShowing setState function to the MainNav that will call it when I press a button.
Then in the App.js I will show or hide the modal if the setIsModalShowing is true or false
inside of the modal I am showing SecNav and the modal also has the setIsModalShowing passed down so that you can click on the button to close is and that will set the state to false.
Does that makes sense to you ? or else I can try to explain it in another way
Code example
I am facing a weird issue that DOM gets re-render in case of any input key pressed in input field. I am using FormControl. sibling component to the input field on DOM has OnPush
strategy.
when i enter anything or click in the input field my DOM get re-render, input field value has no effect on the sibling component so its #Input properties remain same( Strategy of this component is onPush) but it re-render causing no call of lifecycle method like ngOnInit , ngOnChanges.
because of this unpredicted component re-rendering causing distorting of component UI because no lifecycle get call like ngOnInit ngOnChanges so no initialisation function call of that component.
so component get render with previous values can anyone tell me why this is happen.
is this because of FormControl i am using or something else.
I am new to React and Redux, and I have the following sample code.
```
<React.Fragment>
<Spinner />
<TableWrapper
onClick={
()=>{sendActionToToggleIsLoading();
sendActionToChangeTableData()}
}
/>
</React.Fragment>
```
Two components, a Spinner and a Table, they both use its own container to connect to the redux store.
The Spinner connects to a isLoading props and the TableWrapper connects to an array [tableData] in store.
The onClick event on TableWrapper will send two actions to change isLoading and [tableData] in the store and cause two components to update.
My problem is TableWrapper will take a bit time to update, and Spinner doesn't. However the Spinner won't update until TableWrapper finishes componentDidUpdate.
So the behavior now is after onClick, the two components both stuck for a while and then both update to the new state.
My goal is to let the Spinner to update as soon as onClick is triggered and the TableWrapper updates itself.
Am I doing something wrong?
Maybe try to dispatch the loading action inside sendActionToChangeTableData(), I cant tell you why, but it works for me
All the examples I have found that keep local state can't provide an initial value for the input. In my case a parent component retrieves field from a server and passes these to my input form where the fields shall be editable. But I don't want to pass each change back up the hierarchy if I can avoid it, rather only when the form is submitted (either via button or by pressing enter)
Update: the usage is as follows. Imagine a todo list. The top level holds the list and the detail component. When I click at the list the detail should update to show the selected todo text. That text should be editable.
So as far the the detail component goes the initial state of the input is the text from the list that gets passed down in props. It needs to change when a different todo in the list is selected. On the other hand I should be able to edit it and when submit triggered that todo text should be passed back up via a callback prop.
So I have to keep local state to collect the input, but I want that state to be initialized with the existing todo text from the list. If I use the Facebook example of an uncontrolled form, I find the edited text remains displayed when I switch to a different todo in the list. Maybe I'm doing it wrong or is it a conceptual problem? Using controlled input initializing the state in the constructor doesn't work either because the constructor only gets called once (not on each re-render)!
I solved the problem by using the lifecycle method componentWillReceiveProps(nextprops) where I can set the state to the new props. This method gets called each time a re-render becomes necessary - in my case because the parent changes the childs props.
See https://facebook.github.io/react/docs/react-component.html#componentwillreceiveprops
You can set the initial state based on the property passed in from the parent, then edit that state in the component before submitting with the form submission