Using React, I wish to get the audio element.
var AudioPlayer = React.createClass({
componentDidMount: function () {
console.info('Audio: component did mount');
var audio = React.findDOMNode('audio');
console.info('audio', audio);
},
render : function() {
return (
<audio src="/static/music/foo.mp3" controls />
);
}
});
But I keep receiving the error:
Error: Invariant Violation: Element appears to be neither ReactComponent nor DOMNode (keys: 0,1,2,3,4)
Surely lowered components are React classes?
It works using the component references:
var AudioPlayer = React.createClass({
componentDidMount: function () {
console.info('[AudioPlayer] componentDidMount...');
this.props.el = React.findDOMNode(this.refs.audio_tag);
console.info('audio prop set', this.props.el);
},
render: function() {
console.info('[AudioPlayer] render...');
return (
<audio ref="audio_tag" src="/static/music/foo.mp3" controls autoplay="true"/>
);
}
});
Related
The setState call in question is working despite the warning. The warning only occurs after the component on which I am calling setState has been removed, and then rerendered. Why am I getting this warning when the component is already mounted?
<div id="contentArea">
{this.state.activePlugin?this.state.activePlugin.render():null}
</div>
the render method returns a react element:
render(){
return <DatasetsList />;
}
state.activePlugin is set to null and the component containing the jsx code above is rerendered, this is how removing the 'activePlugin' happens. When render is called again and returns the <DatasetsList /> for the second time, subsequent clicks inside the component produce this warning, despite the fact that the setState calls they initiate in fact work as expected.
In other words, the warning appears to be misleading, as the code is working as expected.
componentDidMount() {
this.unsubscribe = this.props.store.listen(s=>{
this.setState(s);
});
}
https://jsfiddle.net/taylorallred/69z2wepo/29874/
var Hello = React.createClass({
getInitialState: function() {
return {
activePlugin: Plugin
}
},
togglePlugin: function() {
this.setState({
activePlugin: this.state.activePlugin ? null : Plugin
})
},
render: function() {
return <div >
< div onClick = {
this.togglePlugin
} > Hello {
this.props.name
} < /div> < div > {
this.state.activePlugin ? < Plugin / > : null
} < /div> < /div>;
}
});
var Plugin = React.createClass({
render: function() {
return ( < MyComponent / > );
}
});
var MyComponent = React.createClass({
getInitialState:function(){
return {a: 1};
},
componentDidMount:function(){
window.setInterval(function(that){that.setState({a: that.state.a++})}, 2000, this);
},
render: function() {
var a = this.state.a;
return <div > MyComponent { a }< /div>;
}
});
ReactDOM.render( < Hello name = "World" / > ,
document.getElementById('container')
);
It's probably because your component is receiving updates when it's not rendered and that component is trying to render because it's state changed. See the fiddle. Click to remove the component and you'll get that error in the console.
The warning was referring to the old unmounted instance of my component which was still listening to the store, as shown in the question. Simply unsubscribing from the store inside componentWillUnmount solved the issue.
componentWillUnmount() {
this.unsubscribe();
}
I have a Container component, it gets a few children.
on componentDidUpdate i would like to change a style attribute.
seems like the Container should be able to handle this, instead of each child handling itself.
Problem, react throws an error when trying to get Dom node of child.
var childA = this.props.children[0];
React.findDOMNode(childA);
=> Uncaught Error: Invariant Violation: Element appears to be neither ReactComponent nor DOMNode (keys: )
EDIT: That ^^^ was the wrong way to write react!
If your children need to do something, you should always try to pass it down from the top.
lets say you have 3 colors: green,red,blue and you want your children to be colored that way, but maybe they change order often. pass it down
Parent = React.createClass({
renderChildren: function(){
var colors = ["red", "blue", "green"]
return React.Children.map(this.props,children, function(child, index){
// this returns a legit clone, adding one extra prop.
return React.cloneElement(child, {color: colors[index]});
})
},
render: function(){
return (
<div>{this.renderChildren()}</div>
)
}
})
Child = React.createClass({
render: function(){
return (<div style={{background: this.props.color}}>{'YOLO'}</div>)
}
})
What you are trying to do is not a recommended practice when working with React. Don't modify the DOM yourself, use state and props.
Children components:
var ChildrenA = React.createClass({
render: function() {
return <div style={{color: this.props.color}}>Hello A</div>;
}
});
App:
var App = React.createClass({
render: function() {
return (<div>
<div>Hello {this.props.name}</div>
<div>
<Container/>
</div>
</div>);
}
});
Container:
var Container = React.createClass({
getInitialState: function(){
return {color: "red"}
},
toggle: function(){
this.setState({
color: this.state.color == "red" ? "blue" : "red"
})
},
render: function() {
return (<div onClick={this.toggle}>
<ChildrenA color={this.state.color}/>
<ChildrenB/>
</div>);
}
});
JSFiddle: https://jsfiddle.net/3m8wLcgk/
You might want to check this out: Thinking in React
I'm trying to call a component function on a child component RouteHandler.
var Bar = React.createClass({
baz: function() {
console.log('something');
},
render: function() {
return <div />;
},
});
var Foo = React.createClass({
baz: function() {
this.refs['REF'].baz();
},
render: function() {
return <RouteHandler ref="REF" />;
},
);
Where RouteHandler is a Bar but this.refs['REF'].baz is undefined.
See https://facebook.github.io/react/tips/expose-component-functions.html for more information on component functions.
I don't believe react-router currently supports exposing component functions on RouteHandlers and the current hacky workaround is to do:
this.refs['REF'].refs['__routeHandler__'].baz();
See https://github.com/rackt/react-router/issues/1597
I write next reactjs 0.13.2 class with jsx template
var ImageTest = React.createClass({
getInitialState:function(){
return {image:"https://pp.vk.me/c1432/g6369227/c_194fa45c.jpg"};
},
render: function () {
return <img src={this.state.image}/>;
}
});
$(document).ready(function () {
React.render(<ImageTest/>, document.getElementById('card'));
});
I worked in Intelj Idea and have File watcher. FW run Babel task for transform this file to clean JS. And this file worked in browser Chrome
"use strict";
var ImageTest = React.createClass({
displayName: "ImageTest",
getInitialState: function getInitialState() {
return { image: "https://pp.vk.me/c1432/g6369227/c_194fa45c.jpg" };
},
render: function render() {
return React.createElement("img", { src: this.state.image });
}
});
$(document).ready(function () {
React.render(React.createElement(ImageTest, null), document.getElementById("card"));
});
And throw next Exception on page load
Warning: Only functions or strings can be mounted as React components.
Uncaught TypeError: undefined is not a function
function autoGenerateWrapperClass(type) {
return ReactClass.createClass({
tagName: type.toUpperCase(),
render: function() {
return new ReactElement(
type,
null,
null,
null,
null,
this.props
);
}
});
}
This function in Reactjs raise exception, row this type.toUpperCase(). For img type==Object, if use <div> type==div. Whats wrong in code?
You need to ensure you're exporting the right components in your modules. The error occurs when the component passed doesn't exist (undefined)
I have a component with a list of items. I want each time I add or remove an item from the list to have animation. Everything it's OK with that.
My only problem is that I want to disable the animation first time when the component initialize.
http://jsfiddle.net/kb3gN/6887/
var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;
var Hello = React.createClass({
getInitialState: function () {
return {items: []};
},
addColor:function(){
this.setState({items:this.state.items.concat('new color')});
},
componentDidMount: function () {
var items = ['blue', 'red', 'green'];
this.setState({items: items});
},
render: function () {
var contentList = this.state.items.map(function (i,k) {
return (<li>{i}</li>);
});
return (
<div>
Hello <button onClick={this.addColor}>add</button>
<ReactCSSTransitionGroup transitionName="example">
{contentList}
</ReactCSSTransitionGroup>
</div>
)
}
});
React.render(<Hello name="World" />, document.body);
So, how can I make the animation appear only when changing the list and not ont the very first setState from didMount method?
Using componentWillMount instead of componentDidMount it will work perfectly as shown in this fiddle : http://jsfiddle.net/ghislaindj/jpuyd3gb/1/
However, if your real code must fetch the data in DidMount, you should use ssorallen comment.