In my project I have App.js that is Parent component. And for Parent component there are two child components those are Childone component and Childtwo component. Now I am trying to pass data from Childone component to Childtwo component. Someone please tell me to achieve this
This is App.js
import React, { Component } from "react";
import Childone from "./Childone/Childone";
import Childtwo from "./Childtwo/Childtwo";
class App extends Component {
render() {
return (
<div className="App">
<Childone />
<Childtwo />
</div>
);
}
}
export default App;
This is Childone
import React, { Component } from "react";
class Childone extends Component {
render() {
const Employs = ["Mark", "Tom"];
return <div className="Childone" />;
}
}
export default Childone;
This is Childtwo
import React, { Component } from "react";
class Childtwo extends Component {
render() {
return <div className="Childtwo" />;
}
}
export default Childtwo;
If you feel I am not clear with my doubt, please put a comment.
There are two ways of doing it.
By passing data from Childone to Parent through callback and from Parent to Childtwo as prop. Thereby letting parent be the intermediatory.
By creating a context at the parent and let Childone be the producer and Childtwo be the consumer.
Context is used to avoid prop drilling. Also frequent update of context values isn't considered as a good practice.
Also, for your case we can go with approach ( 1 ).
You can enter data in Childone and see the data reflect in Childtwo in this sandbox.
Are you familiar with React's unidirectional data flow? I would try to create a mental model in your head of having the Parent be the container/controller that passes the required information into your children.
So in this case you would either want the data to originate from Parent or have some event handler associated with the data in Child1. If the latter, attach a callback function from Parent to Child1 that accepts the data as an argument to then be passed into Child2.
best solution is is to use redux. If you are not familiar with redux then you can follow below approach :
import React, { Component } from "react";
import { render } from "react-dom";
import "./style.css";
class App extends Component {
constructor() {
super();
this.state = {
number:[0]
};
}
render() {
return(
<div>
<div>Parent Componet</div>
<Child1 passToChild={this.passToChild.bind(this)}> </Child1>
<Child2 number={this.state.number}></Child2>
</div>
)
}
passToChild(number){
this.setState({
number : [...this.state.number,number]
});
}
}
class Child1 extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<div>Child1</div>
<button onClick={() => this.sendToSibiling()}>
Send data to sibiling
</button>
</div>
);
}
sendToSibiling() {
this.props.passToChild(Math.random());
}
}
class Child2 extends Component {
constructor(props) {
super(props);
}
render(){
return(
<div>
<div>Child 2</div>
<span>data from sibiling : {...this.props.number}</span>
</div>
)
}
}
Related
I need a little help. I'm working on a project that uses Class Components in React and I got stuck with a issue.
How can I pass datas using props?
For example, imagine that I have one Component that have an array in the state:
import React,{Component} from "react";
class CarList extends Component{
constructor(props){
super(props);
this.state = {
carList: ['Jeep', 'Kwid','HB20','Ônix', 'Prisma', 'Gol quadrado']
}
}
render(){
return(
<div>
</div>
);
}
}
export default CarList;
And now I have to call this array in a Option Tag inside a Select Tag.
Let's imagine this component Bellow:
import React from "react";
import { Component } from "react";
import CarList from "./components/Datas";
class App extends Component{
render(){
return(
<div>
<p>I got it! Here is the car list:</p>
<select>
{this.state.CarList.map( (item,x)=>{
return(
<option key={x}>{item}</option>
)
})}
</select>
</div>
)
}
}
export default App;
This piece of code does not work.
the console.log says: "Uncaught TypeError: this.state is null"
I know that I could create a div with my datas and call with , but I have to use props to pass the datas between the Components.
How can I create a callback function using props to resolve this?
Hi!
I tried to call using this.state, but I got "this.state is not defined"
To pass your data as a props you have to pass it to your child component like this from your parent component :
class ParentComponent extends React.Component {
state = {
carList: [],
};
constructor(props) {
super(props);
this.state = {
carList: ['Jeep', 'Kwid', 'HB20', 'Ônix', 'Prisma', 'Gol quadrado'],
};
}
render() {;
return (
<div>
<ChildComponent carList={this.state.carList || []} />
</div>
);
}
}
and then it is accessible in your child component with this.props.
you can use this props in child component like this:
class ChildComponent extends React.Component {
render() {
return (
<div>
{this.props.carList.map((cars, index) => {
return (
<span key={index}>
{cars}
<br />
</span>
);
})}
</div>
);
}
}
Edit -
if you want to see source code : https://stackblitz.com/edit/react-ts-ddcylu?file=Parent.tsx
I have a class based parent component like below
import React from "react";
import ReactDOM from "react-dom";
import FunChild from "./FunChild";
class App extends React.Component {
constructor(props) {
super(props);
this.childRef = React.createRef();
this.parentmethodFun = this.parentmethodFun.bind(this);
}
parentmethodFun() {
this.childRef.current.childmethod();
}
render() {
return (
<div>
<FunChild />
<button type="button" onClick={this.parentmethodFun}>
function
</button>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("container"));
the funChild.js file
import React from "react";
function FunChild(props) {
childmethod() {
console.log("child method is called");
}
return (<div>This is child ...!</div>);
}
export default FunChild;
if that child was a class component I can very easily use ref={this.childRef} to access child method.
But, it's a functional component and It was giving lot of problems. Can anyone please help me on this.
reference project link https://codesandbox.io/s/react-playground-forked-74xzn?file=/index.js
You should avoid this kind of relation because it is not the way how react works. In React you should pass everything from up to bottom. But if you reale want to achieve something like this you can use reference forwarding and imperative handler hook. E.g:
import { Component, forwardRef, createRef, useImperativeHandle } from "react";
const Child = forwardRef((props, ref) => {
useImperativeHandle(ref, () => ({
childMethod() {
console.log("child method is called");
}
}));
return <div>This is child ...!</div>;
});
class App extends Component {
constructor(props) {
super(props);
this.childRef = createRef();
this.parentmethodFun = this.parentmethodFun.bind(this);
}
parentmethodFun() {
this.childRef.childMethod();
}
render() {
return (
<div>
<Child ref={(ref) => (this.childRef = ref)} />
<button type="button" onClick={this.parentmethodFun}>
function
</button>
</div>
);
}
}
Personally, i think you should rethink your application structure as it is very likely that there is a better solution than this trick.
State is the smart component which store all the states of child components
import React from 'react';
import TextArea from './Components/TextArea';
class State extends React.Component {
constructor(props) {
super(props);
this.state = {
name: ''
}
this.myChangeHandler = this.myChangeHandler.bind(this)
}
myChangeHandler = (event) => {
event.preventDefault();
this.setState({
[event.target.name]:event.target.value
});
}
render() {
return (
<div>
{/* Change code below this line */}
<TextArea name = {this.state.name}
myChangeHandler = {this.myChangeHandler}/>
{/* Change code above this line */}
</div>
);
}
};
export default State;
Now TextArea is the child component which share the input value to state.
import React from 'react';
import '../style.css';
class TextArea extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<input type="text" onChange= {this.props.myChangeHandler} name="name" value={this.props.name}></input>
<h1>Hello, my name is:{this.props.name} </h1>
</div>
);
}
};
export default TextArea;
There are several child components that send the data to state component.
so the app component is used to order the child component.
I need two parents for a child component. please see the image enter image description here
import React from 'react';
import { BrowserRouter, Route } from 'react-router-dom'
import './App.css';
import TextArea from './Components/TextArea'
function App() {
return (
<div className="App">
<BrowserRouter>
<Route path = "/new" component= {TextArea} />
</BrowserRouter>
</div>
);
}
export default App;
You can't have two "direct" parent for a single component but you can have multiple indirect parents.
Example:
App is the parent of State
State is the parent of TextArea
App is also a parent of TextArea but not a direct one.
This means that you can pass props (data and functions) from the top parent to all of his children.
If you need to pass a function from App to TextArea you need to pass it by State.
Here a tutorial on how to do it.
You can also use the Context and here's a tutorial on how to do it.
I'm kinda new to react and thought that in the constructor function, using super(props) can fully receive the props that passed by parents. But however, I can't get the string test from my parent component.
So in the parent component, I pass the string "test" as props
import React from 'react';
import Post from '../components/post';
import "../components/css/post.css"
class Bulletin extends React.Component {
render()
{
console.log(this.props);
return (
<div>
<Post test={"sent from parent"}/>
</div>
);
}
}
export default Bulletin;
And then in Post.js, I print the props in two places:
import React, { Component } from 'react';
export default class Edit extends Component {
constructor(props) {
super(props);
console.log(props);
}
render() {
console.log(this.props);
return (
<div className="editor" onClick={this.focus}>
</div>
);
}
}
The two outputs are both {className: "editor"} which is not what I need. I need the string {test: "sent from parent"} and don't know why this doesn't works for me.
Home Component
import React, { Component } from 'react';
import Two from 'components/Two.jsx'
import One from 'components/One.jsx'
class Home extends Component {
constructor(props){
super(props)
this.state = {
}
this.one = React.createRef();
}
getData = (data) => {
this.one.current.finalClick(data);
}
render() {
return (
<div>
<Two shareData={this.getData} />
<One ref={this.one} />
</div>
);
}
}
export default Home;
One Compoent:
import React from 'react'
class One extends React.Component {
constructor(props){
super(props);
this.state={
}
}
finalClick = (data) => {
console.log(data)
}
render(){
return (
<div>
</div>
)
}
}
export default One;
Two Component:
import React from 'react'
class Two extends React.Component {
handleClick = (data) => {
this.props.shareData(data)
}
render(){
return (
<div>
<br/>
<button className="btn btn-info" onClick={() => this.handleClick('hellow')}>click</button>
</div>
)
}
}
export default Two;
Here i am tring to get click one function from from another components.
which is not it's parent or child componet.
First I am clicking the button in two and it is sending data to Home Component.
And it is logging the data.
And i wants to send data to finalClick() method in the same time after getData() called in Home Component.
My finalClick() function in One Component getting clicked but data is not going.
Save the data that you want to share in the state of Home. Pass a function from Home to Two through Two's props in order to update the data. Pass the data from Home's state down to One in the props.