Update a react components state from its parent - reactjs

Is it ok to update React components state by calling its member function from its parent. Something like:
class SomeComp extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
updateState(data) {
this.setState({ data: data })
}
render() {
return (<div>this.state.data</div>);
}
}

Is it ok to update React components state by calling its member function from controller?
Yes, you can do that but it's unnecessary. Usually you want to update the child state by passing down props from the parent. I've made some examples of how you can update a Child from the Parent below.
Example 1:
In this example, you don't need any state for the Child. The Parent manages the state and passes down any changes to the Child via props. This is the recommended approach.
Parent
class Parent extends React.Component {
constructor() {
super();
this.state = {text: "hello"};
}
render() {
return <Child data={this.state.text} />;
}
}
Child
class Child extends React.Component {
render() {
return <span>{this.props.data}</span>;
}
}
Example 2:
In this example, we use two states, one for each component. This is unnecessary for this implementation, but you can still do it. When the Child mounts, we set the state to whatever the data prop is set to. We update the state whenever the Child component receives props with componentWillReceiveProps().
Parent
class Parent extends React.Component {
constructor() {
super();
this.state = {text: "hello"};
}
render() {
return <Child data={this.state.text} />;
}
}
Child
class Child extends React.Component {
constructor(props) {
super(props);
this.state = {childText: props.data};
}
componentWillReceiveProps(nextProps) {
if(nextProps.data !== this.props.data)
this.setState({childText: data});
}
render() {
return <span>{this.state.childText}</span>;
}
}
Example 3:
In this example, the Child component is given a ref which we then can use to trigger a Child function from Parent. Usually this is done in the reverse order (triggering a function from Child to Parent), but you can still do this if you want. This is the more manual approach and similar to what you asked.
Parent
class Parent extends React.Component {
constructor() {
super();
this.state = {text: "hello"};
}
triggerUpdate = () => {
this.child.component.update(this.state.text);
}
render() {
return <Child ref={(el) => this.child = el} data={this.state.text} />;
}
}
Child
class Child extends React.Component {
constructor(props) {
super(props);
this.state = {childText: props.data};
}
update = (text) => {
this.state({childText: text});
}
render() {
return <span>{this.state.childText}</span>;
}
}

Related

Why doesn't go my props to child component when I changed my props in Main Component?

When I change my state, I can read newData in Main Component but my update state doesn't go my ChildComponent. I read only initialData in my ChildComponent. Why doesn't go my new props to ChildComponent? or Why doesn't reRender my ChildComponent ?
class Main extends Component{
constructor(props) {
super(props);
this.state = {
data: "initalData",
}
}
componentDidMount(){
this.changeState();
}
changeState(){
this.setState({data: "newData"})
}
render(){
console.log("my data in Main :",this.state.data)
return(
<ChildComponent dataProps={this.state.data}>
)
}
class ChildComponent extends Component{
constructor(props) {
super(props);
const getData = props.dataProps;
console.log("getData is ",getData)
this.state = {
...,
}
}
}
It's because the constructor of the class component only run once when you initialize it but not every render.
To always get the latest value, you would need to put them inside the class component body below the constructor.
Something like this:
class ChildComponent extends Component{
constructor(props) {
super(props);
this.state = {
...
}
}
const getData = this.props.dataProps;
console.log("getData is ", getData)
render() (
...
)
}
You can use the below to update each time props that get passed to it changes
componentDidUpdate(prevProps, prevState, snapshot){
if(prevProps !== this.props){
this
}
}
ComponentDidUpdate docs

how to pass just the function from one component to other component without passing the whole component or button click

I am new to react and in a bit of a problem . I have a component, component1. which has a function.
class ReportModal extends React.Component {
constructor(props) {
super(props);
this.state = {
modal: false,
imagesList: [],
code: []
};
this.toggle = this.toggle.bind(this);
}
toggle() {
this.setState({
modal: !this.state.modal
});
}
render() {
return(
<component1/>
)
}
I want to pass the toggle function in another component, component2
class Report extends React.Component {
constructor(props) {
super(props);
this.state = {
modal: false
};
}
render() {
return(
<component2/>
)
}
How do I pass just the toggle function from one component to another without passing the whole component or using a click event
You will have to firstly set the hierarchy of your components such as parent, sibling or child component. You can pass information from parent to child component through props.
Reverse flow occurs as a callback function.
If you want to call a function from parent component, create a function inside it and pass function as props.
class ReportModal extends React.Component {
constructor(props) {
super(props);
this.state = {
modal: false,
imagesList: [],
code: []
};
this.toggle = this.toggle.bind(this);
}
toggle(modal) {
this.setState({
modal: modal
});
}
render() {
return(
<component2 mod={this.toggle}/>
)
}
The child component will call this function on the occurrence of event and provide child data.
class Component2 extends React.Component {
constructor(props) {
super(props);
this.handleClick=this.handleClick.bind(this);
}
handleClick(){
this.props.mod(true)
}
render(){
return (
<button onClick={this.handleClick}></button>
)}
}

How would I get Child's state in parent in initial load itself?

I have a child component which has initial state amount: "0.00"
During initial load, the parent should also have this state received from child and set it as parents state.
The approach that I was thinking about is during componentDidMount call a function in Parent and pass the value to setState.
However I was wondering if there is a better way to go about this.
The initial value need to be in child itself first.
class Parent extends Component{
constructor(){
super();
this.state = {
amountToDisplay: '0.00'
};
---------
class ChildCard extends Component{
constructor(props) {
super(props);
this.state = {
amount: "0.00",
};
}
During initial load itself I needs to change the amountToDisplay to the initial state of child which is "0.00".
In Parent, define a function and pass it down as a prop to Child. Then in Child, call that function in componentDidMount(), we can pass in the value from child up to parent like this:
Parent
class Parent extends Component{
constructor(){
super();
this.state = {
amountToDisplay: '0.00'
};
setInitialAmount = (amount) => {
this.setState({
amountToDisplay: amount
})
}
render(){
return(
<ChildCard setInitialAmount={this.setInitialAmount}/>
)
}
}
Child
class ChildCard extends Component{
constructor(props) {
super(props);
this.state = {
amount: "500.00", //or set to any amount you need
};
}
componentDidMount(){
this.props.setInitialAmount(this.state.amount)
}
}
In constructor of child component itself we can call the parent function after set the values to state in child component
Parent
class ParentComponent extends Component{
constructor(){
super();
this.state = {
amount: '0'
};
getAmount= (amount) => {
this.setState({
amount: amount
})
}
render(){
return(
<ChildCard getAmount={this.setAmount}/>
)
}
}
Child Component
class ChildComponent extends Component{
constructor(props) {
super(props);
this.state = {
amount: "21",
};
this.props.setAmount(this.state.amount)
}
}

Can't pass state value from child to parent component in react native

I have a state inside of child component that I want to use in parent component. This is how my components set:
Child:
export default class Child extends React.PureComponent {
constructor() {
this.state = {
value: "123",
};
}
updateValue(data){
this.props.updateValue(data);
}
componentWillMount(){
this.updateValue(this.state.value);
}
}
Parent:
export default class Parent extends Component {
constructor() {
super(props)
this.state = {
newValue: ""
};
}
updateState (data) {
this.setState(newValue: data);
}
render() {
return(
<Child updateValue={this.updateState.bind(this)}/>
)
}
}
However, it doesn't seem to work and gives me an error. Am I doing something wrong?
Remember that this.setState takes an argument. You have passed a key:value pair that isn't stored in a data structure.
this.setState(newValue: data);
should be
this.setState({newValue: data});

Accessing/Changing Parents State from Child Class using props (React)

I am trying to set state of the parent class with the child. But having trouble figuring out how to do this. I've abstracted away anything I deemed irrelevant to the question at hand. The issue is that I am
Class Parent extends Component {
constructor(props){
super(props)
this.state = {
foo: "bar"
}
}
coolMethod(n){
this.setState({foo: n})
}
render{
return(
<Child coolmethod={this.coolMethod} />
)
}
}
Class Child extends Component {
constructor(props){
super(props)
}
componentDidMount(){
let that = this;
videojs('my-player', options, function onPlayerReady() {
this.on('end',()=>{
that.props.coolMethod(<whatever string returns as a result of
this method>)
})
})
}
render{
return(
// irrelevant stuff to this question
)
}
}
Currently this code gives me "type error: this.setState is not a function"
If you want more info on videojs: http://videojs.com/ (though this is irrelevant to the question by itself, other than the fact that I reference it in my videojs call in componentDidMount of the child)
I assume the 2nd class is Class Child extends Component .... You need to bind this.coolMethod in your Parent constructor first.
Class Parent extends Component {
constructor(props){
super(props)
this.state = {
foo: "bar"
}
this.coolMethod = this.coolMethod.bind(this);
}
coolMethod(n){
this.setState({foo: n})
}
render{
return(
<Child coolmethod={this.coolMethod} />
)
}
}
Try this, tested working on my side, found two issues in the code
Javascript is case sensitive coolmethod is passed in to the Child, but you are trying to access coolMethod.
You need this > this.coolMethod = this.props.coolMethod.bind(this); in the constructor to inherit the setState function from the Parent, otherwise, this inside the coolMethod will be undefined.
import React, { Component } from 'react';
export default class Parent extends Component {
constructor(props){
super(props)
this.state = {
foo: "bar"
}
}
coolMethod(n){
this.setState({foo: n})
}
render(){
return(
<Child coolMethod={this.coolMethod} />
)
}
}
class Child extends Component {
constructor(props){
super(props)
this.coolMethod = this.props.coolMethod.bind(this);
}
render(){
return(
<button onClick={() => this.coolMethod("aabbcc")}>1</button>
)
}
}

Resources