I have two components as below:
class Parent
{
componentWillMount () {
console.log('parent componentWillMount');
}
}
class Child extends Parent
{
componentWillMount () {
console.log('child componentWillMount');
}
}
But when the child component is loaded the componentWillMount method of the parent component is not loaded automatically. How do you call componentWillMount method of the parent component ?
Thanks
class Child extends Parent
{
componentWillMount () {
super.componentWillMount() ; //parent componentWillMount
console.log('child componentWillMount');
}
}
explain :
Child#componentWillMount overrides Parent#componentWillMount. So :
if you need only logic of Parent#componentWillMount without adding extra-logic, it is recommended to remove componentWillMount from Child .
If you need to call Parent#componentWillMount with appending some logic, retain Child#componentWillMount and call inside it super.componentWillMount();
You can call a parent's method in the follow manner:
class Child extends Perent {
componentWillMount () {
super.componentWillMount();
// Insert your child specific code here
}
}
But as Ben Nyrberg already mentioned in the comments it's not a good practice.
The good practice of reusing components code by following the React way is with components composition:
class Parent extends React.Component {
componentWillMount() {
// Reusable functionality here
}
render() {
return {this.props.children}
}
}
class Child extends React.Component {
componentWillMount() {
// Child specific functionality
}
render() {
return <div>Whatever you want</div>
}
}
class App extends React.Component {
render() {
return <Parent>
<Child />
</Parent>
}
}
Related
Is there any side effect I do not see by doing this ?
class App extends React.Component {
hello() {
console.log("hello")
}
render() {
return <Layout app={this}>
}
}
So later on I can refer to this.props.app.hello (and others) from Layout ?
This is not safe.
React will not know how to watch for changes, so you may miss re-renders. React uses === to check for state changes, and App will always be === to App, even when state or properties change.
Take this example:
class App extends React.Component {
constructor(props) {
super(props);
this.setState({text: 'default value'});
}
hello() {
this.setState({...this.state, text: 'new value'});
}
render() {
return (
<div onClick={this.hello}>
<Layout app={this}>
</div>
);
}
}
class Layout extends React.Component {
render() {
return <div>{this.app.state.text}</div>
}
}
When you click on the parent div, this.hello will be called, but the child component will not detect the state update, and may not re-render as expected. If it does re-render, it will be because the parent did. Relying on this will cause future bugs.
A safer pattern is to pass only what is needed into props:
class App extends React.Component {
//...
render() {
return (
<div onClick={this.hello}>
<Layout text={this.state.text}>
</div>
);
}
}
class Layout extends React.Component {
render() {
return <div>{this.props.text}</div>
}
}
This will update as expected.
Answer
There's nothing wrong in passing functions as props, as I can see in your example, the only thing you have to do is make sure your function is bound to the current component like the following example
Reference
React: Passing Functions to Components
I am working on React application and making something like a framework where I have a wrapper component some thing like this.
class FrameworkComponent extends React.Component {
someFunction() {
// send data to child data using childs function
// something like this.some.thing.childFunction("mydata");
...
}
render() {
return (
<div>
<div><button onClick={this.someFunction}>Click me</button></div>
<div>{this.props.child}</div>
</div>
)
}
}
and using it like this :
class SecondComponent extends React.Component {
childFunction(dataRecived) {
alert(dataRecived);
}
render() {
return <div>Hello world</div>;
}
}
import FrameworkComponent from '../FrameworkComponent';
import SecondComponent from '../SecondComponent';
class OtherComponet extends React.Component {
render() {
return (
<div>
<FrameworkComponent>
<div><SecondComponent /></div>
</FrameworkComponent>
</div>
)
}
}
So here I want child's component receive data from parent wrapper component either by updating its child props : componentWillReceiveProps() or calling its child method.
Your best bet would be to use HOC - Higher - https://reactjs.org/docs/higher-order-components.html
I have BaseComponent, from which all another components inherit. But if child component has componentDidMount(), parent's componentDidMount() is not called. Is there any way to call componentDidMount() of parent's component always after componentDidMount() of child component? Here is example.
You can use the "super()" function to call the parents implementation.
componentDidMount() {
console.log('Child mounted.');
super();
}
But this is regarded as an anti-pattern. The suggested approach would be composition (details here). Unfortunately, without know what you are trying to accomplish through inheritance, we can't tell you an alternative through composition. In using your example, it can be done something like this
class Animal extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
console.log('Parent mounted.'); // Not working.
}
render() {
return (<div>{this.props.animalType}</div>);
}
}
class Dog extends React.Component {
componentDidMount() {
console.log('Child mounted.');
}
render() {
return (<Animal animalType="Dog" />);
}
}
React.render(<Dog />, document.body);
In your example, your parent component Animal is not actually the parent but is an independent component since anyways you are rendering the Dog component.
This is the Reason that the componentDidMount of Animal Component is not getting called, in fact the Animal component itself is not being rendered but just defined.
In order for Dog to be a child of Animal component, render it from the Parent component(Animal) and change the code like
class Animal extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
console.log('Parent mounted.'); // Not working.
}
render() {
return (
<Dog/>
)
}
}
class Dog extends Animal {
componentDidMount() {
console.log('Child mounted.');
}
render() {
return <div>Dog.</div>;
}
}
React.render(<Animal />, document.body);
JSFIDDLE
I have custom component in my reactjs application:
class Word extends React.Component {
click() {
// can i access app instance here?
}
}
Your question is not precise but I am assuming you have top level App component which has child components and you are asking if child component can access App component.
If thats the case then just pass reference to it as a prop:
class App extends React.Component {
render() {
<Word parent={this} />
}
}
class Word extends React.Component {
click() {
console.log(props.parent);
}
}
However I believe this to be anti-pattern.
I have a file named separatefile.jsx, in this file parent component name is Content and child component name is Child.
separatefile.jsx
import React from 'react';
import Parent from './learning.jsx';
class Content extends React.Component {
constructor() {
super();
this.state = {
finding : 'i am finding'
}
}
render() {
return (
<div>
<Child childprop={this.state.finding}/>
<Parent/>
</div>
);
}
}
class Child extends React.Component {
render() {
return (
<div>
<h2>{this.props.childprop}</h2>
<h1>child class property</h1>
</div>
);
}
}
export default Content;
This is another file named as learning.jsx , this file has Parent component named as Parent and Child component named as a Children.
My questions is that i need to access Parent component property(parent component for learning.jsx) from Child component(child component for separatefile.jsx file)...
learning.jsx
import React from 'react';
class Parent extends React.Component {
constructor() {
super();
this.state = {
searching : 'i will find the solution'
}
}
render() {
return (
<div>
<Children childrenprop={this.state.searching}/>
</div>
);
}
}
class Children extends React.Component {
render() {
return (
<div>
<h2>{this.props.childrenprop}</h2>
</div>
);
}
}
export default Parent;
If I understood you correctly, you want to use Parent's state in your Children component?
You can pass it down the component tree as props, e.g.:
class Content extends React.Component {
constructor() {
super();
this.state = {
finding : 'i am finding'
}
}
render() {
return (
<div>
<Child childprop={this.state.finding}/>
<Parent finding={this.state.finding} />
</div>
);
}
}
class Parent extends React.Component {
constructor() {
super();
this.state = {
searching : 'i will find the solution'
}
}
render() {
return (
<div>
<Children finding={this.props.finding} childrenprop={this.state.searching}/>
</div>
);
}
}
class Children extends React.Component {
render() {
return (
<div>
<h2>{this.props.childrenprop}</h2>
<div>{this.props.finding}</div>
</div>
);
}
}
It's probably not a direct answer but if you are starting a new app I would recommend you to use Redux with react-redux.
Redux is a predictable state container for JavaScript apps.
It helps you write applications that behave consistently, run in different environments (client, server, and native), and are easy to test. On top of that, it provides a great developer experience, such as live code editing combined with a time traveling debugger.
It's very small library so it's easy to understand how everything works. It might be a good solution to your problem.
Todo app example
You can also check out awesome egghead.io free tutorial - Getting Started with Redux
Here is the answer about the redux benefits by its author Dan Abramov
The React documentation provides an answer.
For communication between two components that don't have a
parent-child relationship, you can set up your own global event
system. Subscribe to events in componentDidMount(), unsubscribe in
componentWillUnmount(), and call setState() when you receive an event.
Flux pattern is one of the possible ways to arrange this.