I have Main Component file and use in another child component.
I have to get state of the child component.
Ex :- Home (Parent)
- Form (Child) component i have been set the value of any text box in state. So ho can i get the state value of Form component into the main component.
Generally in React (and React-Native) information is passed down from the parent component to its children. However if you need to change something in the parent component's state based on the child-component's state, you can pass a function to the child that does just that.
For example:
// Inside Parent Component
openModalFromParent() {
this.setState({ modalOpened: true });
};
// Passing Function to Child
<ChildComponent openModal={ this.openModalFromParent } />
// Inside Child Component
<TouchableHighlight onPress={ () => this.props.openModal() } />
In this example the button in the child component would trigger a function that alters the state of the parent component - hope this helps!
Pass the function as a prop to the child component
//Parent Component
export default class Home extends Component {
constructor(props) {
super(props);
this.state = {
username: '',
password: '',
};
this._handleChange = this._handleChange.bind(this);
}
_handleChange(e) {
const { name, value } = e.target;
this.setState({
[name]: value
});
}
render(){
return(){
<Form valueChange={this._handleChange} />
}
}
}
//Child Component
export default class Form extends Component {
render(){
return(){
<div>
<input type="email" name="username" onChange={(e) => this.props.valueChange()} value={username}/>
<input type="password" name="password" onChange={(e) => this.props.valueChange()} value={password}/>
</div>
}
}
}
In React, your state can only flow down from the parent to the children.
What you should do is move the state from the child to the parent and then pass the state to the child as props.
Try reading this: https://reactjs.org/docs/lifting-state-up.html
Related
I am facing issues while updating the values. Initially I am taking the values from the parent class to put into the text box, and then if I want to update the values into the form through the child component it should basically set the state in child component and pass the updated values to the API. But now when I try to change the values in the text box, it only changes one character and doesn't keep track of the state of all the props. How can I solve this? I have tried using the defaultValue it does change the values but it cannot keep track of the state change.
PS: The updateToApi is just a sample function that is using post to update values into the api
my sample project is here
https://codesandbox.io/s/sad-perlman-ukb68?file=/src/parent.js
#class Parent#
import React from "react";
import "./styles.css";
import Child from "./child";
class Parent extends React.Component {
constructor() {
super();
this.state = {
data: {
username: ["mar"],
name: [null]
}
};
}
updateToApi(data) {
var username: data.username;
var name: data.name;
}
render() {
return (
<Child data={this.state.data} updateToApi={this.updateToApi.bind(this)} />
);
}
}
export default Parent;
##class Child##
import React from "react";
import "./styles.css";
import { Button } from "react-bootstrap";
class Child extends React.Component {
constructor(props) {
super(props);
this.state = {
username: "",
name: ""
};
}
handleSubmit = e => {
e.preventDefault();
};
handleChange = e => {
const data = { ...this.state };
data[e.currentTarget.name] = e.currentTarget.value;
this.setState({ data });
};
render() {
return (
<>
<form onSubmit={this.handleSubmit}>
<label>
Username:
<input
type="text"
name="username"
value={
this.props.data.username !== "undefined"
? this.props.data.username
: this.state.username
}
onChange={this.handleChange}
/>
</label>
<b />
<label>
Name:
<input
type="text"
name="Name"
value={
this.props.data.name !== "undefined"
? this.props.data.name
: this.state.name
}
onChange={this.handleChange}
/>
</label>
<br />
<Button variant="primary" onClick={this.props.updateToApi} />
</form>
</>
);
}
}
export default Child;
Why do you have 2 separate states? You should get rid of the state in your Child component entirely and only work with the Parent's state. Put HandleChange function in your Parent component also and pass it down through props.
UPD
Well, if you want for changes in your inputs to be visible, you could change the onchange handler in your Child coponent to
handleChange = e => {
this.setState({
[e.currentTarget.name] : e.currentTarget.value });
};
and the Input value just to this.state.username
Though i'm still having hard time to grasp what you are trying to accomplish here. Having 2 separate conditional states for the input fields is just too complicated. Imagine if your app would be a bit more complex? You'd lost yourself to debugging this stuff:
value={ this.props.data.username !== "undefined"
? this.state.username
: this.state.username
}
So here i highly recommend you to reevaluate all your data strucuture and data flow within the app. You should have the least amount of sources of truth within your app. Ideally one. So just use the main state in the Parent component and pass down the props that are required.
I have an array which I want to save in my database. I have a page (parent component) and a form (child component) where my birthday input is (the one I'm saving in database). The select html elements are in the child component, and I take their values after every change. Now I need to pass recieved values from select elements back to my parent component and update the array with the recieved props. I will try to recreate my code as best as I can:
AuthenticationPage.js (Parent):
import React from 'react';
class AuthenticationPage extends Component {
constructor(props) {
super(props);
this.state({
setMonth:null
setDay:null
setYear:null
})
}
render() {
return(
<div>
<SignupForm // This is where I call my child component
onChange={(monthValue) => this.setState({ setMonth: monthValue })}
initialValues={{
dateofbirth: [
{
month: this.state.setMonth, // This one is okey but I can use onChange just to change one state
day: this.state.setDay,
year: this.state.setYear
}
]
}}
/>
</div>
)
}
}
export default AuthenticationPage;
SignupForm.js (Child):
import React from "react";
import SelectSearch from "react-select-search";
const SignupForm = (props) => (
<FinalForm
{...props}
render={(fieldRenderProps) => {
const {
// Here I render props from parent component
} = fieldRenderProps;
function monthPicker(monthValue) {
props.onChange(monthValue);
// How can I update the state of setDay and setYear states in parent component
}
return (
<Form className={classes} onSubmit={handleSubmit}>
<SelectSearch
options={month}
onChange={(monthValue) => monthPicker(monthValue)} // This is ok, I change setMonth state in parent with this function
/>
<SelectSearch
options={day}
// How to work with this, this is day input
/>
<SelectSearch
options={year}
// How to work with this, this is year input
/>
</Form>
);
}}
/>
);
export default SignupForm;
So basically I want to update states in parent component after onChange happens on select elements in my child component. I'm new to React and I can't figure this out whole day, so any help will mean a lot.
Child should receive a 'onChange' function prop. That will be called inside the child component, every time the values on the form are changed (this.props.onChange(newValue)).
The parent should hold a state of the values that will be updated accordingly (<SignupForm ... onChange={(newValue) => this.setState({ value: newValue })} />)
From parent to child you can pass data through props, but from child to parent best way is by function , i ll try to write an example below, i always code with functional component so my syntax won't be right below, but i hope you ll get the idea ...
Parent Component
class Parent extends React.Component {
constructor(props) {
super(props);
this.state({
monthValue:null
})
}
// this function send as a prop
const updateMonthValue =(value)=>{
this.state.monthValue=value
}
render() {
return <Child updateMonthValue={updateMonthValue} />;
}
}
Child Component
const Child =(props) => {
const submitHandler =(value) =>{
//here you can call the function of parent and the function in the parent will update state of parent
props.updateMonthValue(value)
}
render() {
return <h1><button onClick={()=>submitHandler("june")} /></h1>;
}
}
I have a component that I can change how it is rendered based on a prop (added a failed state, and based on whether it fails or not it turns red or stays the original colour), the logic for whether failed is true or false is in the parent component.
I want to change the failed state, but only onBlur (without changing the child component). Is there a way to pass in an onBlur function which applies changes to a child prop?
Ive tried a number of different things like:
Child component
<input
failed={failed}
onBlur={onBlur}
/>
Parent component:
this.props.failed = value;
}
and in the render function:
onBlur={() => this.handleBlur(newValue)}
but it didnt work for me.
Props are data that are passed from a parent to its children and are made available through this.props in the child component.
You maintain whatever prop your are passing to child component either in parent component's state or in redux/flux state (if you have global state management).
When failed is modified, a state change should be triggered on parent component, which in-turn will trigger a re-render inside child component.
For example:
In the following, we pass failed as a prop, and onFailureUpdate function as a callback trigger to child component from parent.
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
failed: false
}
}
onFailureUpdate = (value) => {
this.setState({
failed: value
});
}
render() {
return (<ChildComponent failed={this.state.failed} onFailureUpdate={this.onFailureUpdate} />)
}
}
In child component, on blur, we are using the function we passed as prop to modify state in parent, which in-turn will re-render child component.
class ChildComponent extends React.Component {
onBlur = (e) => {
this.props.onFailureUpdate(e.target.value);
}
render() {
return (
<input
value={this.props.failed}
onBlur={(e) => this.onBlur(e)}
/>
)
}
}
Other way:
Or, if there's no necessity for props or parent-child relationship, you can eliminate the need for parent container and go for state maintenance in child.
class RewrittenChildComponentWithState extends React.Component {
constructor() {
this.state = {
failed: false
};
}
onBlur = (e) => {
this.setState({
failed: e.target.value
});
}
render() {
return (
<input
value={this.state.failed}
onBlur={(e) => this.onBlur(e)}
/>
)
}
}
Hope this solves your confusion.
essentially I have a form component for users to fill out. When they complete an action: onChange={onChange} it returns a value (child component);
function onChange(value) {
console.log("This is: ", value);
}
I want to pass the value to a state in the parent component (so that the from can be processed and form data sent). How can I do this? My constructor looks something like this (parent component);
constructor(props) {
super(props);
this.state = {
form: {
name: '',
age: '',
value: ''
}
};
}
Trying to learn react, please go easy as I'm unsure of how to do this. Would love any feedback! Thanks!
Please read the official documentation start guide carefully and patiently when you are a starter.
In react component, state is the internal state and props is the state passed from outside.
You could only modify the state by setState method.
As for the question you ask, you could define a callback function which call setState in parent component, then pass the callback function as props into the child component.
As Zhili said, you should define a function in your parent component that is passed as prop to the child component.
Here's a brief example:
const Child = ({ onSubmit }) => (
<form onSubmit={onSubmit}>
{ /* your <input/>'s here ... */}
</form>
);
class Parent extends React.Component {
state = {
value: null,
};
onChildSubmit = (value) => {
this.setState({
value,
});
}
render() {
return (
<div class="Something">
<Child onSubmit={} />
</div>
)
}
}
I have created and rendered another component. On a button click, I want to do some calculations and then change some props on that other component so it will update its view. How would I do this?
If they need to be state values instead of props, that's ok. Can the setState() be called from another component?
class MainComponent extends React.Component {
other: null,
constructor(props, children)
{
//Create the component
this.other = ReactDOM.render( otherReactElement, document.body );
}
...
//An on Click handler
handle: function(evt)
{
//This is what I want to do
other.setProps( { aPropToChange: "new value" } );
}
};
The "setProps" is deprecated. What else can I do to enable something like that?
If you want to pass new props to other, you have to call ReactDOM.render() again with the new props as you can see here.
I have created a jsfiddle where you can see how to update the props and the state correctly.
class MainComponent extends React.Component {
constructor(props)
{
super(props);
this.other = ReactDOM.render( <Hello name="World"/>, document.getElementById('otherComponent') );
}
changeState(evt)
{
this.other.setState({lastName: "setState works"})
}
changeProps(evt){
this.other = ReactDOM.render( <Hello name="New Name" /> , document.getElementById('otherComponent') );
}
render(){
return <div>
<button onClick={this.changeState.bind(this)}>Change state</button>
<button onClick={this.changeProps.bind(this)}>Change props</button>
</div>
}
};
In React, a parent component can change the state of its child component using refs. Using refs, you get a reference to the child component and you can use that reference to invoke a function inside a child component and that function can have the setState() call inside it.
You can read more about react refs here: https://facebook.github.io/react/docs/more-about-refs.html#the-ref-callback-attribute