React: Add child element after parent component has mounted - reactjs

I have a parent component with child elements. I tried to add a child element after the parent component mounted:
class Parent extends React.Component {
componentDidMount() {
this.props.children.push(<NewChildComponent/>)
}
render() {
return (
<div>
{this.props.children}
</div>
)
}
}
Can someone tell me
1. How to add a child element after a parent has mounted
2. Why the above did not work

It's not working because you are mutating the props array manually - React has no idea that it has changed. In general, you should never change props at all.
If you really want to do this, you can use setState within componentDidMount, and then render your child component through that:
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
childComponent: null
}
}
componentDidMount() {
this.setState({ childComponent: <div>Hello</div> });
}
render() {
return (
<div>
{this.state.childComponent}
</div>
)
}
}
However, there might be a better solution to whatever you're trying to do. I can't imagine many situations in which you'd want to render stuff only after the parent has mounted.

Can you please try componentWillMount, I guess this will fix the problem

Related

I passed a prop "function" to a child component => Error props is undefined

I'm new to ReactJs and I'm trying to pass a function to my child component that updates a state in the parent component!
It seems like the child component can't find the passed function.
The errors message I'm receiving when I click:
TypeError: this.props.cencelLogin is not a function
Another one when I access child component "this is a console error that doesn't crash the program":
Warning: Cannot update during an existing state transition (such as within render). Render methods should be a pure function of props and state.
I console.log(this.props) = I can't find any evidence that getBackCancelLoginForm is exists. "I'm new to this"
I watched a few videos of components communication. It seems that this technique is working; however, this technique is not working for me because of a minor mistake.
this is my parent class component:
class Menu extends Component {
constructor(props){
super(props);
this.state = {
show: 'Defualt'
};
this.getBackCancelLoginForm = this.getBackCancelLoginForm.bind(this);
}
getBackCancelLoginForm = (showVal) => {
this.setState({ show: showVal });
}
render() {
this.CheckShowMenu();
return (
<div>
{ this.state.show === "Defualt" ? <DefualtMenu cencelLogin={this.getBackCancelLoginForm}/> : (<div> </div>)}
</div>
);
}
}
this is my child class component:
class loginCom extends Component {
constructor(props){
super();
this.state = {
cancelSignIn: "Defualt",
};
this.cancel = this.cancel.bind(this);
}
cancel(props){
this.props.cencelLogin(this.state.cancelSignIn);
}
render() {
return (
<div>
<div className="headerCancelBox" onClick={this.cancel.bind(this)}>
</div>
);
}
}
In the actual result: the sing in form should desperate.
when clicking 'X' on the child component -> the function cancel should fire which call the prop function.
which cause child function to be replaced with another child function "Default Menu"
I find my silly mistake! I have to admit that I spend hrs on solving this.
I will leave the answer here forever get the same issue!
I just passed the prop to the wrong child function. :)

Reactjs coding with parent and child component

I have 3 components, that is 2 child components and one parent component.
I wanted to pass the child component value to parent (only the values not the components enitirely,it should not visible in parent) and this values from parent to another child component.
Any suggestions or logic of how to proceed on this, since I don't have any guidance as of right now I had to ask here. Is the above problem possible.
The code is very complex, so I have not put here.
Thank you
When you say values, do you mean state, props, user input, something else?
If you mean state or props: React has a 1-way data flow, so the easiest way to accomplish this is to actually store the data at a higher level. Either store the data used by the child in the parent and pass it down to the children for consumption, or else use a store that both parent and children have access to. Either way, this will make it much easier for all components to access the data.
If you mean user input: one way you can accomplish this is to pass a callback from the parent component to the child as a prop, and then in the child call that callback when a user does something or changes some value. The callback function can make the data accessible to the parent on that user action, and then you can decide what to do with the data from there.
AksharaDL,
Child to Parent — Use a callback and states
Parent to Child — Use Prop
Also here is another article explaining it: https://medium.com/#ruthmpardee/passing-data-between-react-components-103ad82ebd17
here is the solution.
in parrent component you have a state. and have a setData method to update state. pass setData to ChildOne use props. and data to ChilTwo and use it
class StoreBanner extends React.Component {
constructor() {
this.state = {
data: 'whatever'
}
}
setData = (data) => {
this.setState({data})
}
render() {
return (
<div>
<ChildOne setData={this.setData}/>
<ChildTwo data={this.state.data}/>
</div>
)
}
}
and in ChildOne you can update the parrent state
class ChildOne extends React.Component {
setParentData = () => {
this.props.setData('another')
}
...
}
You can do it like this.
class ParentComp extends React.Component {
constructor() {
super();
this.state = {
theStateToPass: null
}
this.receiveDataFromChild = this.receiveDataFromChild.bind(this);
}
receiveDataFromChild(data) {
this.setState({
theStateToPass: data
})
}
render() {
return (
<div>
<FirstChild updateMe={this.receiveDataFromChild} />
<SecondChild stateFromFirstChild={this.state.theStateToPass} />
</div>
)
}
}
class FirstChild extends React.Component {
constructor(props) {
super(props);
this.callParentMethod = this.callParentMethod.bind(this);
}
callParentMethod(e) {
let someDataToSend = "ABC";
this.props.updateMe(someDataToSend)
}
render() {
return (
<div onClick={this.callParentMethod}>
</div>
)
}
}
class SecondChild extends React.Component {
render() {
return (
<div>
{this.props.stateFromFirstChild}
</div>
)
}
}
however it becomes complex and might lead to one's pulling their hair out. so i would suggest using redux , it keeps the flow simple , you have a reducer , actions and a container. everything goes with a flow and keeps it clean but it does comes with an extra overhead of more code as you will be creating container reducer and actions.

react component - parent child interaction; component Lifecycle

I am developing a simple browser app to get some specific data from the user.
I have several components to simplify the proccess of collecting that data, but I am currently rethinking my way of rendering this component.
Basically, i have my main component, which uses state to keep track of which component to render.
I am doing this for almost all of my components.
Also, i also have a function inside the parent component, that i pass to the child component via props, and that is used as a callback to pass the child state to its parent, when that component is no longer useful.
class Main extends React.Component {
constructor(props){
this.state = {
renderA: true,
renderB: false,
childState: null
}
}
collectState(state){
this.setState({
childState: state
});
}
render() {
let content = null;
if(this.state.renderA === true){
content = <ComponentA />
} else {
content = <ComponentB />
}
return(
<div>
{content}
</div>);
}
}
So, using the above example, the child would be something like this
class ComponentA extends React.Component {
constructor(props){
super(props);
this.state = {
stop: false,
usefullInfo: null
}
destroy() {
this.props.collectstate(this.state.usefullInfo)
}
render(){
render something (like a Form) untill this.state.usefullInfo is set;
in that case, set this.state.stop true which will call destroy, passing the usefull information to parent
}
}
So, this method works for me, but i can see clearly that most probably this is not the way to do this.
At this point my question are:
1) how can I stop rendering a component without having to track it with some property like this.state.stop ?
2) if i want to render 2 different components, like in the main component, do I always have to keep a renderA and renderB property on state, to render one or another?
3) is there a better way to pass information from child to parent? i am currently using a callback function passed via props from parent to child, and i am invoking that callback when the component has done its purpose
4) any general suggestions on how to improve the quality of the above code?
Thank you for you help :)!
Your example works fine, but in React it is recommended to lift state up when handling data from multiple children (source). So I would recommend to keep the sate of every children in the parent, and pass props with values and handlers to the children.
Here's a sample app you can check. The form components handle the case you want to implement.
To answer your questions:
The parent component should decide, based on its own state, whether to render a child component or not.
It's not needed to keep variables on state about what component to render. that should be computed in render() based on the parent's state
Yes, callback are the recommended way to pass information to parents
Code quality looks good. You can always do good with tools like prettier or ESlint.
Here's an example:
class Main extends React.Component {
constructor(props) {
this.state = {
stateA: '',
stateB: '',
};
}
handleStateChange(name, value) {
this.setState({
[name]: value,
});
}
render() {
const { stateA, stateB } = this.statel;
const shouldRenderA = !stateA;
if (shouldRenderA) {
return <ComponentA value={stateA} onChange={value => this.handleStateChange('stateA', value)} />;
}
return <ComponentB value={stateA} onChange={value => this.handleStateChange('stateB', value)} />;
}
}
class ComponentA extends React.Component {
render() {
const { value, onChange } = this.props;
return <input type="text" value="value" onChange={onChange} />;
}
}

How to send or update data as state or prop to app.jsx from child component

I am new in react js.
I need to change the whole view on click of button
For this i need to update parent component's state from child component.
Like we do as a session variable. Do you guys have any idea about it then please help me out.
Thanks in advance.
This is my code :
App.jsx
class App extends React.Component {
constructor(props) {
super(props)
}
render() {
let RedirectTo = this.state.page;
let RenderPage;
switch (RedirectTo) {
case 'component':
RenderPage = true && <NextPage />;
break;
default:
RenderPage = true && <Index />;
}
return (
<div>
{RenderPage}
</div>
);
}
Child.jsx
class Child extends React.Component {
constructor(props) {
super(props);
this.state = {redirect: 'yes'};
this.state = {page: 'component'};
}
render() {
if (this.state.redirect === 'yes') {
return (
<div>
{ true && <App /> }
</div>
);
} else {
return (
<div>
<a onClick={this.Validate} href="javascript:void(0);">
Click To Next
</a>
</div>
);
}
}
First, React component working on Parent to child manner not child to parent, whatever function you want to call which can affect your parent from child then you have to pass the props into child and invocation happen through the parent so that will affect your parent as well as child,
What you want to tried to achieve is wrong way you have to introduce the Router in your application which can route the one page to another one you need to check the React-Router for that so basically navigation of one component to another component we can easily achieve using react-router, React-Router
Just make a function in parent like
function () {
// your functionality here
}
then call the child component in parent as
<child functionProp = {this.function} />
In your child component call the function in parent by
this.props.functionProp
In parent you can pass a function as props to the child as:
<child someFunction={this.handleFunction} />
And in handleFunction method in parent you can do whatever you want.
handleFunction(value) {
//do something
}
And in child you can call that someFunction as:
this.props.someFunction(value)
In this way you can communicate to parent through child.

React — onScroll listener for parent element?

How can I add an onScroll listener in a component to catch a scroll of a parent element?
class ChildDiv extends React.Component {
constructor() {
super();
}
handleScrollOfParent() {
// do stuff when parent <main> scrolls;
}
render() {
return (
<div id="child" onScroll={this.handleScrollOfParent.bind(this)}>
// content with overflow: hidden and scroll handled by parent MAIN.
</div>
)
}
}
export default ChildDiv;
Rendered in a parent main, like this <main><ChildDiv /></main> and I want to catch the scroll of the main.
You could either:
1) try to grab the parent node from the child component:
componentDidMount() {
ReactDOM.findDOMNode(this).parentNode.addEventListener(...
}
2) pass the parent node as props and attach listener after rendered:
In parent:
render{
return(
<div className="parent" ref={(elem)=>{this.node=elem}}>
<Child parentNode={this.node}/>
</div>
)
}
and in child (parentNode is still undefined in constructor, check in next props):
componentWillReceiveProps(newProps){
newProps.parentNode.addEventListener(...
}
According to React's nature, which is passing props from Parent down to Children, so when you want the Child element to update its parent, you need to create a function on Parent, and pass to the Child as props
Please also refer to my answer to a similar issue (how to trigger the parent component to do something from the child/grandchild/or great-grandchild):
Re-initializing class on redirect
In your case, we may do something like this:
1/ Create a function on Parent that trigger the Parent itself to do something:
import React from 'react';
class Parent extends React.Component {
constructor(props) {
super(props);
// ...
}
doSomeThingOnParent = () => {
// do whatever you want with this Parent component, setState, forceUpdate etc.
}
render(){
// ...
<Child doSomeThingOnParent={this.doSomeThingOnParent} />
// ...
}
}
2/ On Child Component, trigger the above function using onScroll:
class Child extends React.Component {
...
render() {
return (
<div id="child" onScroll={this.props.doSomeThingOnParent}>
// your content
</div>
)
}
}
However, you cannot render the Parent by your mentioned way, which is:
You should use like the Parent's render method above, and also set the CSS to allow overflow for your Child component
You could define a state variable in the parent component that would store the current scrollTop value (assuming vertical scrolling) and update in every time the scroll event happens and then pass this variable to the ChildDiv which could detect that the variable has changed in componentWillReceiveProps:
if(this.props.yourVariable != nextProps.yourVariable){
// scroll event was fired => scroll position changed
}

Resources