How do you get access to the calling component in react?
function MyCallingComponent() {
return <MyReadingComponent/>
}
function MyReadingComponent() {
console.log(callingComponent.state)
}
You don't. The parent component can pass data and functions to the child via props, though. So for instance, if the parent needed a callback from the child in some circumstance:
function MyCallingComponent() {
function callback() {
// ...
}
return <MyReadingComponent callback={callback}/>;
}
function MyReadingComponent({callback}) {
// ...use `callback` where appropriate...
}
react uses unidirectional data flow, so if you need to access parent's state in your child component you need to pass it down as a prop.
class ParentComponent ...{
state={ foo : 'A' }
render(){
return <ChildComponent foo={this.state.foo}/>
}
}
as #t-j-crowder has said if you need to pass data from child to parent you may use callback method.
Related
i have 3 nested components
<GrandParent />
<Parent />
<Child />
i have a button in my Child component and on double click i would like to call a function in GrandParent component
<button #dblclick="this.$parent.callGrandParentFunction(model)"> call grandparent </button>
using this.$parent i can only access Parent methods ... is there any way to go one level higher and call a GrandParent method ?
there is a similar question on SO but it's about vue2
VueJS Grandchild component call function in Great grandparent component
Try to use provide/inject pattern :
GrandParent :
export default {
methods: {
someMethod(){
//
}
},
provide() {
// use function syntax so that we can access `this`
return {
someMethod: this.someMethod
}
}
}
in GrandChild component :
export default {
inject: ['someMethod'],
created() {
//run the method
this.someMethod()
}
}
I have a technical question. I am trying to pass a value from child component to store by using action dispatcher inside my child component. This action dispatcher then updates the state value in the reducer.
Is it advisable to pass value from the child component this way? will it affect the performance of the react app?
Or should I use props to pass from child to parent component and then update the state.
Please advise as I searched a lot about this but didn't get any info.
Problem with passing dispatcher to your child is your child component is not very reusable. I would suggest to pass a callback method to your child which contains the logic of dispatching the event.
Parent:
class ParentComponent extends React.Component {
loginHandler(){
...
this.props.someMethod();
}
render() {
return {
...
<ChildComponent click="loginHandler"></ChildComponent>
...
}
}
}
const mapDispatchToProps = dispatch => {
return {
// dispatching plain actions
...
someMethod: () => dispatch({ ... }),
...
}
}
export default connect(null, mapDispatchToProps)(ParentComponent);
Child Component:
function ChildComponent({click}) {
return {
...
<button click={click}></button>
...
}
}
Now with this approach your child approach doesn't carry any business logic. It can be used at multiple places.
I have a React component that is wrapped in a HOC. The HOC establishes a subscription within componentDidMount that causes the HOC to rerender whenever the HOC's setState function is called, which rerenders the wrapped component. This is similar to how Redux Connect works.
The issue I have is the wrapped component (child) is responsible for providing the data that HOC, which the requires to establish the subscriptions. It comes from the props passed into the child.
I can see from the console that componentDidMount is not called from the HOC until the wrapped (child) components componentDidMount is executed.
Would it be acceptable to create a handler method that allows the wrapped component to update the class properties of the HOC using this.data = data?
This would allow the HOC to use the data from the wrapped component in order to setup the subscription.
HOC
const HOCComponent= function HOCComponent(config) {
return function returnWrapped(Wrapped) {
return class Wrapper extends Component {
constructor(props) {
this.handleData = this.handleData.bind(this)
this.data = {}
}
comonentDidMount() {
setSubscription(this.data, () => {
this.setState({
key: getData(),
})
})
}
handleData(data) {
this.data = data
}
render () {
<Wrapped handleData={this.handleData} />
}
}
}
}
CHILD
const Component class Wrapper extends Component {
constructor(props) {
// Stuff
props.handleData(props.data)
}
render() {
<div>Hello!</div>
}
}
In the above, props.handleData could also be called from within the componentDidMount of the child.
I want to use the state of my child Component in my parent component in this example . what i want exactly to be able to do is this:
<Application onChange={(myVar)=>{console.log(myVar)}}/>
You're onChange is just a normal prop which you pass into your Application component. So if it's a function you can call it whenever you want. In this case, it makes more sense to call it when Application's state is updated. You can use the second parameter of setState function which is an optional callback function for this. But just make sure you onChange prop is defined and it's a function before you call it with any parameter which you want to pass.
class Application extends React.Component {
constructor(props){
super(props);
this.state = {myVar:0};
setInterval(()=>{
this.setState( { myVar:this.state.myVar + 1 }, () => {
if(this.props.onChange && typeof this.props.onChange === "function")
this.props.onChange(this.state.myVar)
} );
}, 3000);
}
//.....
}
Updated Codepen: https://codepen.io/anon/pen/gWvKxa
So I have a parent component Store that has a child component called Order. The data from the parent is passed via props to its child, like so:
parent
<Order :order="order" />
child
props: ['order']
I need to use a new data variable in the child component called orderIds, so I declare that:
child
props: ['order'],
data: () {
return {
orderIds: Object.keys(this.order)
}
}
Then, I render the orderIds in the view:
{{orderIds}}
Now, whenever the order data changes in the parent, it updates the prop order in the child, but it is not propagated through to orderIds.
How would I update orderIds when something changes in order?
Instead of data use a computed property.
computed: {
orderIds: function () {
return Object.keys(this.order);
}
}