Given the following, is it possible to access the parent context rather than the containers from a child (non-react component) element?
The example logs container, ideally it would log parent. I would like for Parent to be self contained, not to have it's state managed by its container.
var Container = React.createClass({ getInitialState: function () { return { context: 'container' } }, render: function () { return ( <Parent> <a href="#" onClick={function () {console.log(this.state.context);}.bind(this)}>click me</a> </Parent> ); } }); var Parent= React.createClass({ getInitialState: function () { return { context: 'parent' } }, render: function () { return ( <div> {this.props.children} </div> ); } }); If there is another pattern for handling this, please share as well.
Note: To be clear, I understand how the this keyword works and why the above example works as it does. The example is simply meant to illustrate the problem.
3 Answers
Answers 1
You can import some React helpers for that:
var React = require('react') ... var children = React.Children.map(this.props.children, child => { return React.cloneElement(child, { context: this.state.context }) }) render() { return <div>{ children }</div> } ... Then your child component will have this.props.context which will be the string 'parent', but this must be a React component, as this needs to refer to the component using the parent prop
var YourComponent = React.createClass({ render() { return ( <a href="#" onClick={() => console.log(this.props.context)}> click me </a> ) } }) ------ var Parent = require('./Parent') var YourComponent = require('./YourComponent') ... render() { return <Parent><YourComponent /></Parent> } Answers 2
I do not know about the first part of your question, but since you commented about dynamically creating components, here's how I do it:
You can set a state variable in the constructor of the class and its parent:
if (typeof this.state == 'undefined') { this.state = { componentsToRender: <div></div> }; } Then in the parent component, in the componentDidMount() function:
var componentsToRender = []; if ([conditional]) { // some logic so you know which component to render componentsToRender.push(<customChildComponentToRender key={} />); } else { componentsToRender.push(<otherComponentToRender key={} />); } this.setState({ componentsToRender: <div>{componentsToRender}</div> }); Make sure to put a key (lines 4 and 7 of the second code block) or React will scream at you.
In response to your initial question, I would watch this video from the ReactJS Conference 2015 to get more of the heart behind a container. After hearing what the guys at Facebook say (who have radical views on containers!), you might want to rethink the design to make your container more of a data layer.
Answers 3
I would check out THIS article from the react website. I think it might give you some intuition on solving your problem.
As a general rule of thumb, I try and only use this.state to handle internal UI state of a specific component. Everything else is passed via props. If you're needing the full context of a component, I would either pass it as a prop or checkout something like flux or redux which will help you manage state between components.
0 comments:
Post a Comment