call child function from parent in reactjs - javascript

My parent component
import EditReview from './partials/editReview'
class VenueDetails extends Component {
constructor(props) {
super(props)
this.child = React.createRef();
}
render() {
return (
<div className="place-review-text">
<EditReview {...this.props}/>
</div>
)
}
}
My child component
class EditReview extends Component {
onEditClick(review, editIndex) {
console.log('ppp')
}
render() {
const { handleSubmit, user, pristine, index, commentCrossClick } = this.props
return (
<div>
<Field
name="content"
component={renderTextArea}
className="form-control"
label="Write your review..."
rows={2}
/>
</div>
)
}
}
export default EditReview
I need to call onEditClick from the parent component. I tried this but doesn't work.
Kindly help me
Edit
After upgrade I am getting this
Error in ./~/react-dom/lib/ReactServerRendering.js
Module not found: 'react/lib/React' in /home/user/ashish/LTC/lovethesecities-frontend/node_modules/react-dom/lib
After resolving all the errors call child function from parent in react 16

React docs have a example of this using refs
https://reactjs.org/docs/refs-and-the-dom.html
I’m also wondering the use case of wanting to do this, maybe some context could help with an answer?

Try doing it like this:
import EditReview from './partials/editReview'
class VenueDetails extends Component {
render() {
return (
<div className="place-review-text">
<EditReview ref={Ref => this.child=Ref } {...this.props} />
</div>
)
}
}
and call the function in parent component as this.child.onEditClick(param1,param2)
EDIT1:
if you have to do it with react 15.x itself what you can do it is create the function in parent and pass it as a prop to child

Related

How to properly create and render functional components?

I am attempting to create and render a functional component using the instructions here as a base. From what I've sen in there I should be able to do something along the lines of:
class MyComponent extends React.Component {
render() {
return (
<div>
<OtherComponent props="test" />
</div>
)}
function OtherComponent(props) {
return (
<div>
test
</div>
);
}
}
But this throws the error:
Unexpected token: function OtherComponent(props) {
^
I found a few posts that suggested removing the function so I tried that but then it throws the error:
OtherComponent is not defined
I'm able to get it working by creating a separate class component like so:
class OtherComponent extends React.Component {
render() {
But that's not what I want to do. What is the proper way to create/render a functional component in React.js?
For example this one works. See the docs ;)
React - Composing Components
function OtherComponent(props) {
return <div>test</div>;
}
class App extends React.Component {
render() {
return (
<div>
<OtherComponent props="test" />
</div>
);
}
}
Try this
class MyComponent extends React.Component {
OtherComponent = (props) => {
return (
<div>
test
</div>
);
}
render() {
return (
<div>
{this.OtherComponent("test")}
</div>
)}
}
You can't define a component inside of another component. A functional component means that the component is created from a function and is not a class. It can't have it's own state, because the state is initialized in class constructor. Check out this article for more info https://hackernoon.com/react-stateless-functional-components-nine-wins-you-might-have-overlooked-997b0d933dbc
const otherComponent = (props) =>
<div>
test
</div>;
Here is another way. Its not correct to declare a component in a render function. If it is used solely in a parent component why not make that explicit and use static
class MyComponent extends React.Component {
static myOtherComponent = (props) => <div>{'test'}</div>
render(){
return(
<div>
<MyComponent.myOtherComponent {props} />
</div>
)
}
The myOtherComponent behaviour is controlled purely through the props it gets , it won't have its own state.
Or you could just make it a separate component e.g
export default myOtherComponent = (props) => ()
and import it into MyComponent. Please note , now with hooks ( see React Docs ), you can use hooks to mimic state etc in functional components and the latter approach might be your cleanest and most flexible approach.
This way you can define a function component
function OtherComponent(props) {
return <div>{props}</div>;
}
And now you can use functional component in your App (class component) like below
class App extends React.Component {
render() {
return (
<div>
<OtherComponent props="test" />
</div>
);
}
}

React - Passing props to App.js

Recently I learned how to pass props from one component to another. In my case, from <FileTree> to <TextBox>, as you can see here: https://codesandbox.io/s/y018010qk9
But after, I reorganized the code a bit and now it is possible to see the structure of my React App inside <App> (App.js). I decided to put the <FileTree> and <TextBox> side by side, with Bootstrap.
So, logically I thought that passing props from <App> to <TextBox> would be the same as I did before: From <FileTree> to <TextBox>. Unfortunatelly, it is not the case.
At the moment, this is the code inside <App>:
// Structure of the project
export class App extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<div className="col-md-12">
<SearchEngine />
</div>
<div className="col-md-6">
<FileTree />
</div>
<div className="col-md-6">
<TextBox content={this.props.activeNode} />
</div>
</div>
);
}
}
And here, the code inside <TextBox>:
// TextBox component
export class TextBox extends React.Component {
constructor(props) {
super(props);
this.state = {
content: 'Select A Node To See Its Data Structure Here...'
}
this.showContent = this.showContent.bind(this);
}
showContent (newContent) {
this.setState ({
content: newContent
})
}
componentWillReceiveProps (nextProps) {
this.setState ({
content: nextProps.content
})
}
render() {
return (
<div className="padd_top">
<div className="content_box">{this.state.content}</div>
</div>
);
}
}
export default TextBox;
Just in case, here one can find the <FileTree> component:
// Construction of FileTree
export class FileTree extends React.Component {
constructor(props) {
super(props)
this.state = {
activeNode: null
}
this.setActiveNode = this.setActiveNode.bind(this);
}
setActiveNode(name) {
this.setState({activeNode: name})
}
render() {
return(
<div className="padd_top">{
renderTree(
this.props.root || root,
this.setActiveNode,
this.state.activeNode
)
}
</div>
)
}
}
I'm recently getting to know React.js and I'm very thankful for any advice/clarity you can provide.
Thank you.
You need to use lift state method passing state from child to parent then from parent pass it to the child you want
In your parent component create a constructor with states then create liftStateUp function pass it to the child component that you want to receive the data from
constructor(props) {
super(props)
this.state = {
activeNode: '',
}
}
liftStateUp = (data) =>{
this.setState({ activeNode: data})
}
<div>
<div className="col-md-6">
<FileTree liftStateUp={this.liftStateUp} />
</div>
<div className="col-md-6">
<TextBox content={this.state.activeNode} />
</div>
</div>
Then in file_tree.js FileTree function you need to call liftStateUp function that we created it in the parent component
setActiveNode(name) {
this.setState({ activeNode: name });
this.props.liftStateUp(name);
}
https://reactjs.org/docs/lifting-state-up.html
Props are passed down from the parent component to child component. You need to work with global store so that you can interact with state in different siblings of components. For this, you may use redux.
If your application size is smaller, then you may also try using context api.
Hope, this helps to you.

React.JS Call childs component method from Parent Wrapper Component

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

How to make/access state using props in react?

I made an app with multiple components and want their state to be accessed using parent/main app, I'm not sure how to get it. what i'm trying to do is when i change state in main "App" the component state should change. One of the component is 'checkbox' and now i want to access its state using parent app, I made multiple attempts but not getting it done. my code goes like this..
This is Main 'App' code:
import React, { Component } from 'react';
import Checkbox from './checkbox';
import Radio from './Radio';
import ToggleSwitch from './ToggleSwitch';
import PrimaryButton from './PrimaryButton';
class App extends Component {
onClick(isClicked){
isChecked:true
};
render() {
return (
<div id="form">
<Checkbox
onClick={this.onClick}
/>
<RadioButton
onClick={this.onClick}
/>
</div>
);
}
}
export default App;
The component i want to access goes like this:
import React, { Component } from 'react';
class Checkbox extends Component {
constructor(props){
super(props);
this.state={
isChecked:true
};
};
onCheck(){
this.setState({
isChecked: !this.state.isChecked
});
this.props.isClicked()
};
render() {
return (
<div>
<div
className={this.state.isChecked ? 'checked': 'unchecked'}
onClick={this.onCheck.bind(this)}
>
</div>
</div>
);
}
}
export default Checkbox;
You forgot to bind the onClick event in the app component, try this it will work :
class App extends Component {
onClick(isClicked){
console.log('isClicked', isClicked);
};
render() {
return (
<div id="form">
<Checkbox onClick={this.onClick.bind(this)}/>
</div>
);
}
}
If you already have onClick handler for the Checkbox I don't see why you couldn't just move the state up to the App component and just pass down a callback from there to the Checkbox that will update the parent state. That seems like a more React way to do it, to me.
class App extends Component {
constructor(props){
super(props);
this.state={
isChecked:true
}
}
onClick = (isClicked) => {
this.setState({isChecked: !this.state.isChecked})
}
render() {
return (
<div id="form">
<Checkbox
onClick={this.onClick}
ischecked={this.state.isChecked}
/>
</div>
);
}
}
Component
class Checkbox extends Component {
onCheck(){
this.props.onClick()
}
render() {
return (
<div>
<div
className={this.props.isChecked ? 'checked': 'unchecked'}
onClick={this.onCheck.bind(this)}
>
</div>
</div>
)
}
}

Passing a Redux Action to a child component with props

I am trying to set a video in my app as "Featured" when a user clicks on an item. I have an action creator that does a simple console.log() when called, and for testing I call it w/ componentDidMount(), and it works fine. I have a separate component for the VideoItem, and I'm trying to pass down the action creator, but I get an error: TypeError: Cannot read property 'props' of undefined. I tried to add .bind(this) to the end of the action I was passing down, but it didn't make a difference.
If the action creator works when I call it at componentDidMount, why can't I pass it to the child component? Here's my Video and VideoItem component:
// Video.js
import React, { Component } from 'react'
import VideoItem from './VideoItem'
class Videos extends Component {
componentDidMount() {
this.props.actions.getVideos()
// This function works, but getting error
// when passing to VideoItem component
this.props.actions.setFeaturedVideo()
}
constructor(props) {
super(props);
}
render() {
if(this.props.videos.length == 0){
return <p>Loading....</p>
}
return (
<div className="container">
<ul className="row">
{this.props.videos.map(function(result) {
return (
<VideoItem
key={result.position}
setFeaturedVideo={this.props.setFeaturedVideo}
video={result}
/>
)
})}
</ul>
</div>
)
}
}
export default Videos
// VideoItem.js
import React, { Component } from 'react'
class VideoItem extends Component {
constructor(props) {
super(props);
}
render() {
return (
<li className="col m6" onClick={this.props.setFeaturedVideo()}>
{this.props.video.title}
</li>
)
}
}
export default VideoItem
Missed that this inside a map function. Since you are using map, the "this" belongs to the map function. You need to assign this to a variable before the map function and use that instead.
render() {
var _that = this;
if(this.props.videos.length == 0){
return <p>Loading....</p>
}
return (
<div className="container">
<ul className="row">
{this.props.videos.map(function(result) {
return (
<VideoIte
key={result.position}
setFeaturedVideo={_that.props.actions.setFeaturedVideo}
video={result}
/>
)
})}
</ul>
</div>
)
}
I noticed that to the VideoItem Component you have the code passing the function like so
<VideoItem
key={result.position}
setFeaturedVideo={this.props.setFeaturedVideo}
video={result}
/>
But in your componentDidMount you call this.props.actions.setFeatureVideo()
So to me you are not passing the function down as props since you are trying to get it from this.props instead of this.props.actions

Categories

Resources