Reputation: 479
I have this react code where I don't know how to do it better.
I will start like this.
I have 3 react
components as of now, namely Main
, Form
, NextButton
So my Main
component looks like this:
import React, { Component } from "react";
import Form from "./Form";
import NextButton from "./NextButton";
class Main extends Component {
render() {
return (
<div>
<Form />
<NextButton />
</div>
);
}
}
export default Main;
Form
contains some Text Fields, First Name
, Last Name
, Age
And NextButton
component contains a react-bootstrap
Button
just to navigate to the next page with react-router-dom
, nothing fancy.
My problem is:
I want to pass the value of First Name
to the page I render when clicking NextButton
through props
So the NextButton
would look something like this:
<NextButton firstname={value-i-get-from-Form-component}/>
I know react
only allows one-direction data passing, but I want to make this work. Means If my current setup in the Main
component is not right, How should I change it?
Upvotes: 0
Views: 2993
Reputation: 5443
If this were me i would get familiar with using react functional components and hooks since they are way easier to comprehend and understand than redux. They are very powerful and when you write your own hooks you can share logic in a really easy way across components.
function Main() {
const [title, setTitle] = React.useState(undefined);
return (
<div>
<Form onChange={setTitle} />
<NextButton title={title} />
</div>
);
}
function Form({ onChange }) {
const [value, setValue] = React.useState("");
const change = event => {
setValue(event.target.value);
};
return (
<form
onSubmit={e => {
onChange(value);
e.preventDefault();
}}
>
<input onChange={change} type="text" value={value} />
<button type="submit">Submit</button>
</form>
);
}
function NextButton({ title = "Title" }) {
return <button>{title}</button>;
}
ReactDOM.render(<Main />, document.getElementById('app'));
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
<div id="app"></div>
Upvotes: 0
Reputation: 21
You can pass data from Form
to Main
by calling function prop when your First Name
input change.
Main component:
import React, { Component } from "react";
import Form from "./Form";
import NextButton from "./NextButton";
class Main extends Component {
constructor(props) {
super(props)
this.handleChange = this.handleChange.bind(this)
this.state = {
formValue: {}
}
}
handleChange(formValue) {
this.setState(formValue)
}
render() {
return (
<div>
<Form onChange={this.handleChange} value={this.state.formValue} />
<NextButton firstName={this.state.formValue.firstName} />
</div>
);
}
}
export default Main;
Form component can be like:
import React, { Component } from "react";
class Form extends Component {
constructor(props) {
super(props)
this.handleFirstNameChange = this.handleFirstNameChange.bind(this)
this.handleLastNameChange = this.handleLastNameChange.bind(this)
this.handleAgeChange = this.handleAgeChange.bind(this)
}
handleFirstNameChange(event) {
if (this.props.onChange) {
this.props.onChange({
...this.props.value, // keep the other values like lastName, age
firstName: event.target.value,
})
}
}
handleLastNameChange(event) {
if (this.props.onChange) {
this.props.onChange({
...this.props.value, // keep the other values like firstName, age
lastName: event.target.value,
})
}
}
handleAgeChange(event) {
if (this.props.onChange) {
this.props.onChange({
...this.props.value, // keep the other values like firstName, lastName
age: event.target.value,
})
}
}
render() {
let { firstName, lastName, age } = this.props.value
return (
<form>
<input type="text" value={firstName} onChange={this.handleFirstNameChange} />
<input type="text" value={lastName} onChange={this.handleLastNameChange} />
<input type="text" value={age} onChange={this.handleAgeChange} />
</form>
);
}
}
export default Form;
If your component hierarchy getting complicated you can use Redux
.
Upvotes: 0
Reputation: 1651
With a functional component you can keep state in the parent and pass the hook to the child which can then update the parent. You can also pass a handler to the child and use it to update the parent.
With a functional component it could look like this:
function Main(props) {
const [firstName, setFirstName] = React.useState('');
return (
<div>
<Form setFirstName={setFirstName} firstName={firstName} />
<NextButton firstName={firstName} />
</div>
);
}
Inside Form you can update the state like this
function Form({ firstName, setFirstName }) {
const handleChange = (event) => {
setFirstName(event.target.value)
}
return (
<div>
<TextField onChange={handleChange} value={firstName} />
</div>
);
}
This will render that new state in the parent which will pass it to NextButton.
Upvotes: 1