Currently I am using reat creat app to build my appication in my application had three componentes those are com1, com2, com3 I want to update userId state value in com1 based on com3 will recive props here com2 is child component of com1.
Here is my sample code
import comp2 from './comp2.js';
class comp1 extends React.Component {
constructor(props) {
super(props);
this.state = {
userId:""
}
};
click() {
this.setSate({userId:"123"});
}
render() {
<div>Hello Child onClick={this.click}</>
<comp2 data={this.state.userId}
}
}
import comp3 from './comp3.js';
class comp2 extends React.Component {
constructor(props) {
super(props);
};
componentWillReceiveProps(nextProps) {
if (nextProps.data !== this.props.data) {
this.setState({userID:this.state.userId});
}
}
}
click() {
this.setState({userID:"456"})
}
render() {
<div>Hello Child onClick={this.click}</>
<comp3 data={this.state.userId}
}
}
class comp3 extends React.Component {
constructor(props) {
super(props);
};
componentWillReceiveProps(nextProps) {
if (nextProps.data !== this.props.data) {
this.setState({userID:this.state.userId});
}
}
render() {
<div>Hello Child onClick={this.click}</>
<comp3 data={this.state.userId}
}
}
You can use shared store between them or the parent dhould to manage data between children.
Related
Want to use a reference to a dynamically imported component in next js as below. How do I do this?
Given
// component1.jsx
export default class Component1 extends React.Component {
constructor(props) {
super(props)
}
render() {
return (<p>something</p>)
}
doSomething() {
console.log('should work')
}
}
And
// component2.jsx
import dynamic from 'next/dynamic'
const Component1 = dynamic(import('./component1'), {ssr: false})
class Component2 extends React.Component {
constructor(props) {
super(props)
this.myRef = React.createRef()
}
componentDidMount() {
this.myRef.current.doSomething(); // This fails!
}
render() {
return (<Component1 ref={this.myRef}/>);
}
}
Already looked at https://github.com/vercel/next.js/issues/4957 and the solution there just doesn't work?
So I am building my first react project and stumbled upon following problem:
In my App.js (main application) I got a function and render my components:
class App extends Component {
constructor(props) {
super(props);
this.candidateCounter = 0;
this.setCandidateVote = this.setCandidateVote.bind(this);
}
...
setCounter (name) {
this.candidateCounter++;
console.log(this.candidateCounter);
}
render() {
...
<Candidates setCounter={this.setCounter} />
}
}
The child component Candidates.jsx has another function and thus calls another component:
export class Candidates extends React.Component {
constructor(props) {
super(props);
this.AppProps = props;
}
...
registerVote(name) {
...
this.AppProps.setCounter(name);
}
render() {
...
<MyButton id={this.state.candidates[i].name} register={this.registerVote} />
}
And the last component MyButton.jsx looks like this:
export class MyButton extends React.Component {
constructor(props) {
super();
this.ParentProps = props;
this.state = { active: false }
}
buttonActiveHandler = () => {
this.setState({
active: !this.state.active
});
if (this.state.active === false) {
this.ParentProps.register(this.ParentProps.id);
}
else {
...
}
}
render() {
return (
<Button content='Click here' toggle active={this.state.active} onClick={this.buttonActiveHandler} />
);
}
}
I have successfully debugged that all functions calls are working except when the grandchild MyButton has triggered the registerVote() function in my Candidates module. Logging in this method gets printed but it cannot call this.AppProps.setCounter() from the parent App. I receive the following error:
TypeError: Cannot read property 'setCounter' of undefined
I hope this wasn't too complicated explained, any help is appreciated :)
Simply bind the function in the constructor of the class as #qasimalbaqali stated in his comment.
constructor(props) {
super();
this.registerVote = this.registerVote.bind(this);
}
Say you have a parent component:
// ParentComponent
class ParentComponent extends React.Component {
render() {
return(
<ChildComponent/>
)
}
}
From inside the child component, is there a way to access the class name of the parent component without passing this down as props?
// ChildComponent
class ChildComponent extends React.Component {
// ?????
getParentComponentName() {
return this.??? // Should return "ParentComponent"
}
render() {
return(
<div/>
)
}
}
I'd prefer to be able to access this without passing it down as props. Thank you!
You need to access ReactInternalFiber like
class Child extends React.Component {
constructor(props) {
super(props);
this.state = { name: '' }
}
getParentName = () =>{
this.setState({ name: this._reactInternalFiber._debugOwner.type.name })
}
render() {
return (
<div>
<h1>Name: {this.state.name}</h1>
<button onClick={this.getParentName}>Get Parent Name</button>
</div>
)
}
}
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});
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>;
}
}