I've looked up whole google for my answer (haha).
What I am trying to achieve:
My fist screen is a form with some input fields which store the input to state.
By clicking "submit" the user comes to the next page/screen, where the previous input is supposed to show up. I want to show only the input data as a p-tag, not as an input tag anymore.
How do I achieve this? I am bloody new to reactjs.
I've thought about multiple solutions:
store the input data to an external JSON (which seems pretty complicated)
pass the data as props, but I am not aware of how I would do this
Thanks so far!
I'm going to assume that your second screen has the same parent component as your first, something like this:
render() {
return (
<div>
{this.state.showFirstScreen && <FirstScreen />}
{this.state.showSecondcreen && <Secondcreen />}
</div>
)
}
If that's the case, your FirstScreen component can accept a prop called something like onSubmit -- you say that you already store the input values from FirstScreen in state, so when FirstScreen is finished, you can call this.props.onSubmit(this.state) and it will send up the state to your parent component, as long as you've defined a callback function in the parent component:
{this.state.showFirstScreen && <FirstScreen onSubmit={this.onFirstScreenSubmit} />}
Then, you can save the state of the first screen into the state of your Parent component, and pass that part of the state down to SecondScreen
[edit] here's a very crude example: https://jsfiddle.net/df4s9ey8/
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.
There is an UI I have created using React. There are two text fields to enter value, after entering and saving those values will be populated in a table below the two fields(we are using antd for designing).
However when I click a single record in the table and click edit in that particular record data from that record will be populated to the above mentioned text fields. When this happens I want my app to scroll up and show those two text fields which are ready to be edited.
But currently it stays at the same position after clicked edit, without scrolling up and showing two text fields. Here's an image descripting my experience
Check this answer to find how to control srollTop: https://stackoverflow.com/a/55184755/2360631
But I don't think it's a good idea, maybe you can consider to freeze the edit area otherwise when you finish edit you may need to scroll back again...
Basically you want to set focus to some component after a re-render.
To refer to a particular component, use react refs
make a react ref of whatever you want to set focus to and assign it as a ref prop
constructor() {
super();
this.foo = React.createRef();
}
componentDidUpdate() {
this.foo.current.focus();
}
<Bar ref={this.foo}> .... </Bar>
foo is the name of ref
Bar is the component you want to set focus to
in your case it can be a parent of both input fields or any one of the input fields
I want to make custom confirmation modal whenever user wants to delete his own post. How to approach that to use as less as possible code? I was thinking about independent component with logic inside (user can send via props function on yes/no, etc) but the problem I can't figure out is how to mount this component when user click on a button? Do I need to use local state inside every component when I need to use modal? Something like:
showModal ? <Modal onYes={()=>{}} onNo={()=>{}} title='whatever you want' /> : ''
Can I achieve that in other way? I hope I explained well.
You can use HOC as well. Keep show/hide state inside HOC and then pass props/functions (with currying) from Parent component
Small example - https://codesandbox.io/s/withtoggle-hoc-8bd0r
I have the component that displays one button. Clicking this button loads the component which has a back button. I now want to return back to the component when this back button is clicked.
I am new to react and if I search online I see react-routing as the solution. Wouldn't simply rendering the component from component work? Just like was rendered from ?
Parent component has a state named isChildActive.
this.state = {isChildActive: false}
On the render of Parent you instantiate <ChildComponent active={this.state.isChildActive} goBack={() => this.setState({isChildActive: false})} />
And then you add to the onClick callback of the button at ParentComponent: <button onClick ={() => this.setState({isChildActive:true})} />
So that's the simple way of doing it. You own the state at your parent component because in react, data flows unidirectionally, from top to bottom. And then you pass a callback to your children components, to modify that parent owned state, when needed.
The best way of routing is using a library because it is not a simple task and you'll save a lot of time and headaches if you use a well-tested library. The industry standard is react-router
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