Children props are not visible in parent component - reactjs

In child component, I set the props as following:
function mapStateToProps(state) {
return {
user : state.App.get('user'),
foo: 'ok'
}
}
But when I read this.props.children in render method of parent component, foo is not there. Anyone knows why?
I realized that I can't see the child state from a parent in my project. Am I missing something?
I'm also using Redux in this app. Whats wrong? What's the proper way of doing something like this.props.children.foo in parent Component?

You shouldn't be referencing this.props.children.foo to get foo. Once you've connected your component to mapStateToProps, you should be able to reference it just from this.props.foo
this.props.children will retrieve all the elements enclosed within an opening and closing tag of React component.
There is a CodePen example on the React documentation page that illustrates this:
http://codepen.io/gaearon/pen/ozqNOV?editors=0010
function WelcomeDialog() {
return (
<FancyBorder color="blue">
/*everything between these two blocks*/
<h1 className="Dialog-title">
Welcome
</h1>
<p className="Dialog-message">
Thank you for visiting our spacecraft!
</p>
/*is what is sent to FancyBorder as this.props.children*/
</FancyBorder>
);
}
Source: https://facebook.github.io/react/docs/composition-vs-inheritance.html

Related

React Context always returns EMPTY

I have a Search parent component and a SideBar child component, I am trying to get context in SideBar, but everytime it returns empty.
I followed the tutorial exactly like: https://itnext.io/manage-react-state-without-redux-a1d03403d360
but it never worked, anyone know what I did wrong?
Here is the codesandbox link to the project: https://codesandbox.io/s/vigilant-elion-3li7v
I wrote that article.
To solve your specific problem:
When using the HOC withStore you're injecting the prop store into the wrapped component: <WrappedComponent store={context}.
The value of the prop store is an object that contains 3 functions: get, set, and remove.
So, instead of printing it, you should use it. For example this.props.store.get("currentAlbums") or this.props.store.set("currentAlbums", [album1, album2]).
This example is forked by your code: https://codesandbox.io/s/nameless-wood-ycps6
However
Don't rewrite the article code, but use the library: https://www.npmjs.com/package/#spyna/react-store which is already packed, tested, and has more features.
An event better solution is to use this library: https://www.npmjs.com/package/react-context-hook. That is the new version of the one in that article.
This is an example of a sidebar that updates another component content: https://codesandbox.io/s/react-context-hook-sidebar-xxwkm
Be careful when using react context API
Using the React Context API to manage the global state of an application has some performance issues, because each time the context changes, every child component is updated.
So, I don't recommend using it for large projects.
The library https://www.npmjs.com/package/#spyna/react-store has this issue.
The library https://www.npmjs.com/package/react-context-hook does not.
You pass the store as a prop, so to access it, you need this.props.store in your SideBar.
Not this.state.store
Create a wrapping App component around Search and Sidebar:
const App = props => (
<div>
<Search />
<SideBar />
</div>
);
export default createStore(App);
Now you can manipulate state with set and get that you have available in child components Search and Sidebar.
In Search component you can have something like:
componentDidMount() {
this.props.store.set("showModal", this.state.showModal);
}
also wrapped with withStore(Search) ofc.
and in SideBar you can now call:
render() {
return (
<div>
{"Sidebar: this.state.store: ---> " +
JSON.stringify(this.props.store.get("showModal"))}
}
</div>
);
}
and you will get the output.

passing data from child to parent in react and undefind is not a function

I need to pass an array from child component to my parent component .
What i did in parent component is :
handlerfordata=(data)=>{
console.log('Inside handlerfordata data is');
console.log(data);
}
Inide return in render .Note Child is name of my child component
return(
<View>
<Child handlerfordata={this.handlerfordata()}/>
</View>
);
Now inside my child component i have done something like this
handleSave = () => {
//finalvalue is an array that is computed and i can see it in my console and handlesave is triggeed at onclick in child component inside return
console.log('finalValue is ',finalValue);
this.props.handlerfordata(finalValue);
}
Another thing is that child component gets rendered on the screen but i just want to access data from child component and not rendering it .
Pass the reference for handlerfordata and not this.handlerfordata().
It shuld be
<Child handlerfordata={this.handlerfordata}/>
^^^^^^^^^^^^^^^^^^^^^^
By adding this code
<Child handlerfordata={this.handlerfordata()}/>
You are not passing the reference, rather you are calling this function.
Change it to
<Child handlerfordata={this.handlerfordata}/>
which will just pass a reference.
Then you can call that from child component using props.
You have to bind your handler :
<Child handlerfordata={this.handlerfordata.bind(this)} />
Inorder to call the method you need to pass the reference in the child element as
<Child handlerfordata={this.handlerfordata}/>
You cannot access the data from child without rendering the child component.I prefer you to use redux so that all the states are there in a single store.
ReactJS is known for one way data flow(Top down) meaning whatever data that is flowing or passing, should be in one direction, from parent to child.
In the case where you need to pass data the other way round, perhaps try to apply redux state management instead.
In the code that you are trying as stated, it's only passing a method down from parent to child.

How to access data in a child react component from a parent react component

I'm new to ReactJS. I want to be able to set some properties of a React component and then be able to access it from a parent React component. But I'm not entirely sure how to do this. For example, consider the following two classes:
export default class SubWindow extends React.Component {
click(event)
{
this.myCollection.push({name:'receiptNum',value:$(event.currentTarget).html()});
}
render()
{
return (
<ul>
<li onClick={this.click.bind(this)}>0</li>
<li onClick={this.click.bind(this)}>1</li>
<li onClick={this.click.bind(this)}>2</li>
<li onClick={this.click.bind(this)}>3</li>
</ul>
);
}
}
export default class MainWindow extends React.Component {
click(event)
{
console.log(SubWindow.myCollection);
}
render()
{
const SubWindow = require('./SubWindow').default;
return (
<SubWindow />
<button onClick={this.click}>Log subwindow array</button>
);
}
}
Basically, I want the SubWindow to have a property called myCollection which is just an array of JSON objects. myCollection gets populated by each click on the list item.
Later, I want to be able to console.log(SubWindow.myCollection) when I press on a button in the parent window. My question how do I access the SubWindow.myCollection from a parent react component?
I would recommend you to solve this problem by using callback. MainWindow is creating SubWindow, and you can give here a callback function as a property. For example:
<SubWindow onClick={this.onSubwindowClick} />
Now in your SubWindow class, just call this callback inside your click function:
click(event)
{
this.myCollection.push({name:'receiptNum',value:$(event.currentTarget).html()});
this.props.onClick(/* data you want to pass to the parent */);
}
Also you have to define onSubwindowClick in the class MainWindow. This function should receive any data you wish from child class - the data which you pass from child where I put comment /* data you want to pass to the parent */.
Also, don't forget to bind this to that onSubwindowClick function. This is usually done in constructor of the class, which I suggest you to create for each component.
You can find good example about "passing data to parent" on React's pages. You can take a look at the article Thinking in React, particularly section "Step 5: Add inverse data flow".
just pass a function to you child component, and the function is bind to the parent component's 'this', actually you just created a closure.
then in your parent component, the function's args are passed in your child component, meanwhile your parent component's scope has access to the args, so in the parent scope you can get access to the data in the child scope.

React - how to do jQuery style find() to find children of a DOM node?

I've got a component that returns this:
return (
<div className="audio-widget">
<div
className={this.props.className}
onWheel={this.handleWheel}
/>
{controls}
</div>
)
I need to do the equivalent of:
handleWheel(event) {
let $canvas = $('.audio-widget').find('canvas');
[...]
}
The canvas is drawn programatically by a 3rd party script, so I can't just slap an ID on it (especially since this is a component and there are several per page).
Excuse the extreme n00b question, I'm brand new to React. Thanks!
This is a good use case for the ref prop. If you give a component a ref prop, e.g. ref="foo", upon rendering that component will be available as e.g. this.refs.foo. Then you can get the rendered DOM node with React.findDOMNode.
render() {
// ...
return (
<div ref="audioWidget" className="audio-widget">
<div
className={this.props.className}
onWheel={this.handleWheel}
/>
{controls}
</div>
);
}
handleWheel(event) {
let canvas = React.findDOMNode(this.refs.audioWidget)
.querySelector('canvas');
// ...
}
You can learn more about refs here: https://facebook.github.io/react/docs/more-about-refs.html
I think, it's a bad way to direct access 'canvas' with selector, the reason is as follows:
When you component changed, the React will do some diff works, then update your dom with a best way, that means, the node you get with selector may be changed to another node just for 'the best way'.
You can build a 'Child Component', and do something in the 'handleWheel' of the 'Parent Component', then communicate with the 'Child Component' through the 'props' for 'Child Component'

ReactJS Why can't I modify children passed into a component

I figured I could do this, but I am getting this error:
TypeError: child.constructor.ConvenienceConstructor is not a function
I have a component in a page, ala:
// this content is in an html page. My component reads in this child, but I can't seem to modify any part of it.. Just diplay it.
<MyComponent prop1="somevalue">
<div className="myclass1"> some child content that is dynamic </div>
</MyComponent>
Now, in my component since that inner child(ren) is dynamic, I need to change that class depending on some condition. But I can't. I get that error I noted above.
I tried this:
var childContent = React.Children.map(this.props.children,
function(child) {
return React.cloneWithProps(child,
{ className: 'myNEWClass' } );
});
I tried cloneElement too, that didn't work either.
Doesn't work. I tried accessing the child directly, ala:
child._store.props.className // but can't seem to change it, seems immutable.
So, how can I change that class up?
thanks,
Props are supposed to be immutable, so instead of passing className as a prop, you make the parent pass in a prop named defaultClass. In your map method, you can add an extra prop, say, overrideClass. Finally, in the render() method of the actual child component, you need some logic to set the className to either overrideClass, or defaultClass. In this way, you don't have to mutate props.

Resources