Updating State, but not re-rendering in ReactJS? - javascript

I am very new to React and am just getting my feet wet. I'm having a hard time understand why this isn't re-rending the List. Here is my code:
app.jsx
var Hello = React.createClass({
getInitialState: function() {
return {
links: ['test ']
}
},
render: function() {
return <div className = "row">
<Submission linkStore = {this.state.links}/>
<List links = {this.state.links} />
</div>
}
});
var element = React.createElement(Hello, {});
ReactDOM.render(element, document.querySelector('.container'));
In my submission.jsx I have this function to push info into the links array
handleSubmitClick: function() {
this.props.linkStore.push(this.props.text)
this.setState({text: ''})
console.log(this.props.linkStore)
}
My list.jsx looks like this
module.exports = React.createClass({
getInitialState: function() {
return {
links: this.props.links
}
},
render: function() {
return <div>
{this.props.links}
</div>
}
});
Everything works as intended and I can get the test to show appropriately.
I am aware that this isn't going to show up as an actual list and that I should create a list component to show the items in list form. I'm just trying to run tests along the way to see how everything works.

Use parent state instead of child props.
try this
app.jsx
var Hello = React.createClass({
getInitialState: function() {
return {
links: ['test ']
}
},
handleListSubmitClick: function(params) {
this.setState({links:params});
},
render: function() {
return <div className = "row">
<Submission linkStore = {this.state.links} handleListSubmitClick={this.handleListSubmitClick}/>
<List links = {this.state.links} />
</div>
}
});
submission.jsx
handleSubmitClick: function() {
var linkStore = this.props.linkStore;
linkStore.push(this.props.text)
this.setState({text: ''})
this.props.handleListSubmitClick(linkStore);
}
but I don't understand this.props.text. input's value using this.refs.ref
list.jsx
module.exports = React.createClass({
getInitialState: function() {
return {
links: this.props.links
}
},
render: function() {
return <div>
{this.props.links}
</div>
}
});

Related

React not rendering class

I believe I have a syntax area somewhere, but I can't figure it out.
Note: I am new to React and I am using Sharepoint to develop.
My Js file:
var newt = React.createClass({
getInitialState: function () {
return {
greeting: 'This is really',
thing: 'code stuff'
};
},
render: function () {
return (
<div id="react-newt">
{this.state.greeting} {this.state.thing}!
</div>
);
}
});
$(function () {
if (document.getElementById('newt')) {
React.render(
<newt />,
document.getElementById('newt')
);
console.log('newt');
}
});
And my HTML file:
<div id="newt"></div>
I inspect the console and I see this:
You have to use a capitalised name for the component. JSX treats lowercase as a built-in HTML component. See User-Defined Components Must Be Capitalized for more details.
var Newt = React.createClass({
getInitialState: function () {
return {
greeting: 'This is really',
thing: 'code stuff'
};
},
render: function () {
return (
<div id="react-newt">
{this.state.greeting} {this.state.thing}!
</div>
);
}
});
$(function () {
if (document.getElementById('newt')) {
React.render(
<Newt />,
document.getElementById('newt')
);
console.log('newt');
}
});

Display element on increase of counter in ReactJS

I'm new to ReactJS. I need to show a text as many times as user clicks. I have tried but some how it is not working as expected. Please help.
var Paragraph = React.createClass({
renderParagraph: function(){
for(i=0; i<this.props.data;i++){
<p key={i}> Hello World </p>
}
},
render: function() {
return(
<div>
{this.renderParagraph}
</div>
);
}
});
var Container = React.createClass({
getInitialState: function() {
return {
counter: 0
}
},
increment: function() {
this.setState({
counter: this.state.counter + 1
});
},
render: function() {
return (
<div className="well">
<Paragraph data={this.state.counter}/>
<button className="btn btn-primary" onClick={this.increment}> Increase Me
</button>
</div>
)
}
});
React.render(<Container />, document.getElementById('root'));
In the above code, i'm trying to render Paragraph component as many times as user clicks.
Implementation here: http://jsbin.com/jevufu/edit?js,output
Thanks in advance.
You need call method this.renderParagraph() not just pass reference this.renderParagraph., also, from method renderParagraph you need return array with Nodes,
var Paragraph = React.createClass({
renderParagraph: function() {
var paragraphs = [];
for (var i = 0; i < this.props.data; i++) {
paragraphs.push(<p key={i}> Hello World { i } </p>);
}
return paragraphs;
},
render: function() {
return(
<div>{ this.renderParagraph() }</div>
);
}
});
Example

call function inside of className react.js

How do I call the function for getClass for the className inside this example? The way I have it written out does not seem to call getClass.
var CreateList = React.createClass({
getClass: function() {
//some code to return className
},
render: function() {
return(
<div className{this.getClass}>Example</div>
);
}
});
You're referencing the instance of the getClass() function as opposed to calling the function. Try tweaking it like so:
render: function() {
return(
<div className={this.getClass()}>Example</div>
);
}
className{this.getClass} won't compile. Try this:
var CreateList = React.createClass({
getClass: function() {
//some code to return className
},
render: function() {
return(
<div className={this.getClass()}>Example</div>
);
}
});
If you want the div to have a class name that starts with 'className', then prepend that string to the result of the call: className={'className' + this.getClass()}.
functional component
const statusColor = () => {
return 'red';
};
<span className={statusColor()}>your text</span>

Changing the value of a checkbox by inheriting a value in React.js

I'm trying to get familiar with how inheritance works between components in react.js and I'm having a bit trouble.
Requirements - Basically, what I want to achieve is for the value of my check box to change when I click on the button.
The check box is inheriting the value of 'checkedVal', which is set in state in the Heading.
I can get the correct value in the checkbox when it first loads but cannot change it when I click on the button. Any ideas would be appreciated?
var Heading = React.createClass({
propTypes: {
name: React.PropTypes.string,
age: React.PropTypes.number
},
getDefaultProps: function(){
return {
name: 'Keir',
age: 24,
}
},
getInitialState: function(){
return {
manU: false,
checkedVal: false
}
},
manUFan: function(){
this.setState(function(previousState, currentProps){
return {
manU: !previousState.manU,
checkedVal: !previousState.checkedVal
}
});
},
render: function(){
var msg;
if(this.state.manU){
msg = "I am a United fan."
} else {
msg = "I dream of being a united fan."
}
return (
<div>
<h1>Attempting React</h1>
<ul>
<li>{this.props.name}</li>
<li>{this.props.age}</li>
</ul>
<button onClick={this.manUFan}>Do You Support Man U?</button>
<CheckBox checkBoxVal={this.state.checkedVal}/>
<p>{msg}</p>
</div>
)
}
});
var CheckBox = React.createClass({
propTypes: {
checkBoxVal: React.PropTypes.bool
},
render: function(){
return (
<div>
<input type="checkbox" defaultChecked={this.props.checkBoxVal}/>
</div>
)
}
});
ReactDOM.render(<Heading />, document.getElementById('content'));
The defaultValue and defaultChecked props are only used during initial render. If you need to update the value in a subsequent render, you will need to use a controlled component. https://facebook.github.io/react/docs/forms.html#controlled-components
So in your case here's how you'd implement a controlled CheckBox.
var Heading = React.createClass({
...
getInitialState: function(){
return {
checkedVal: false
}
},
handleChange: function(event){
this.setState({checkedVal: event.target.value});
},
render: function(){
...
return (
<div>
...
<CheckBox onChange={this.handleChange} checkBoxVal={this.state.checkedVal}/>
...
</div>
);
}
});
var CheckBox = React.createClass({
propTypes: {
checkBoxVal: React.PropTypes.bool
},
render: function(){
return (
<div>
<input type="checkbox" onChange={this.props.onChange} value={this.props.checkBoxVal}/>
</div>
);
}
});

Search in Backbone Collections, Updating UI with React

I'm spending time on something probably simple:
I'd like to implement a search bar, ideally updating the list of item as-you-type. My small app uses React and Backbone (for models and collections).
Displaying the list isn't too hard, it all works perfectly doing this (the mixin i'm using basically allows easy collections retrieval):
var List = React.createClass ({
mixins: [Backbone.React.Component.mixin],
searchFilter: function () {
//some filtering code here, not sure how (filter method is only for arrays...)
}
}
getInitialState: function () {
initialState = this.getCollection().map(function(model) {
return {
id: model.cid,
name: model.get('name'),
description: model.get('description')
}
});
return {
init: initialState,
items : []
}
},
componentWillMount: function () {
this.setState({items: this.state.init})
},
render: function(){
var list = this.state.items.map(function(obj){
return (
<div key={obj.id}>
<h2>{obj.name}</h2>
<p>{obj.description}</p>
</div>
)
});
return (
<div className='list'>
{list}
</div>
)
}
});
Now i've tried with no success to first translate the backbone collection into "state" with the getInitialState method, my idea was to proxy through a copy of the collection, which then could hold the search results. I'm not showing here my attemps for the sake of clarity(edit: yes i am), could someone guide me to the right approach? Thanks in advance.
There are many ways to accomplish this, but the simplest (in my opinion) is to store your search criteria in the List component's state and use it to filter which items from your collection get displayed. You can use a Backbone collection's built in filter method to do this.
var List = React.createClass ({
mixins: [Backbone.React.Component.mixin],
getInitialState: function () {
return {
nameFilter: ''
};
},
updateSearch: function (event) {
this.setState({
nameFilter: event.target.value
});
},
filterItems: function (item) {
// if we have no filter, pass through
if (!this.state.nameFilter) return true;
return item.name.toLowerCase().indexOf(this.state.nameFilter) > -1;
},
render: function(){
var list = this.props.collection
.filter(this.filterItems.bind(this))
.map(function(obj){
return (
<div key={obj.id}>
<h2>{obj.name}</h2>
</div>
)
});
return (
<div className='list'>
{list}
<input onChange={this.updateSearch} type="text" value={this.state.nameFilter}/>
</div>
)
}
});
var collection = new Backbone.Collection([
{
name: 'Bob'
},
{
name: 'Bill'
},
{
name: 'James'
}
]);
React.render(<List collection={collection}/>, document.body);
jsbin
The search criteria could easily be passed down from a parent component as a prop, so the search input does not have to live inside your List component.
Eventually I also found a different solution (below), but it involves copying the entire collection into state, which is probably not such a good idea...
var List = React.createClass ({
mixins: [Backbone.React.Component.mixin],
searchFilter: function () {
var updatedlist = this.state.init;
var searchText = this.refs.searchbar.getDOMNode().value
updatedlist = updatedlist.filter(function (item) {
return item.name.toLowerCase().search(
searchText.toLowerCase()) !== -1
});
this.setState({items: updatedlist})
}
},
getInitialState: function () {
initialState = this.getCollection().map(function(model) {
return {
id: model.cid,
name: model.get('name'),
description: model.get('description')
}
});
return {
init: initialState,
items : []
}
},
componentWillMount: function () {
this.setState({items: this.state.init})
},
render: function(){
var list = this.state.items.map(function(obj){
return (
<div key={obj.id}>
<h2>{obj.name}</h2>
<p>{obj.description}</p>
</div>
)
});
return (
<div className='list'>
<input ref='searchbar' type="text" placeholder="Search" onChange={this.searchFilter}/>
{list}
</div>
)
}
});

Categories

Resources