Cannot interact between react components - javascript

This is for a react JS project (jsfiddle). The textbox should update with the true/false checked value of the checkbox, but it does not do so. Can someone explain why?
var AutoGenerateCheckbox = React.createClass ({
getInitialState: function() {
return {checked: false};
},
update() {
this.state.checked = !this.state.checked;
alert(this.state.checked);
this.props.onUpdate(this.state.checked);
},
render() {
return (
<input type="checkbox" checked={this.state.checked} onChange={this.update} />
);
}
});
var TBox = React.createClass({displayName: 'TextBox',
render: function() {
return (
<div>
Checkbox value: {this.props.data}
</div>
);
}
});
var KApp = React.createClass({
getInitialState: function() {
return {autoChecked: false};
},
handleAutogenChange: function(val) {
alert('handleAutogenChange:' + val);
this.setState({autoChecked : val});
},
render: function() {
return (
<div>
<AutoGenerateCheckbox onUpdate={this.handleAutogenChange}/>
<TBox data={this.state.autoChecked}/>
</div>
);
}
});
ReactDOM.render(
<KApp />,
document.getElementById('content')
);

The reason you don't see anything printed out is because you are trying to print a boolean value here
<div>
Checkbox value: {this.props.data}
</div>
try
<div>
Checkbox value: {this.props.data.toString()}
</div>
instead.
As an extra tip, you don't really need to hold the state of the checkbox in both its own state and its parent component's state. You really only need to have it in the parent component's state.
See the fiddle I made.

React is not determining the Boolean value to be printable information, try this instead:
<div>
Checkbox value: {this.props.data.toString()}
</div>

Related

Is this the "React.js" way of doing this?

I'm starting with React and I tried to create a simple form that says Hello name!
However I feel having 2 state elements isn't the right way to do this.
Does anyone knows or believes there's a better way to do this?
By the way, I know I can just bind the name state to the h2, but I want it to happen on click.
var Name = React.createClass({
getInitialState:function(){
return {
inputname:'',
h2name:''
};
},
showName:function(event){
event.preventDefault();
this.setState({h2name:this.state.inputname});
},
updateName:function(event){
this.setState({inputname:event.target.value});
}
,
render:function(){
return (
<div>
<form onSubmit={this.showName}>
<input onChange={this.updateName} placeholder="Enter your name"></input>
<button type="submit">Show</button>
</form>
<h2>Hello {this.state.h2name}!</h2>
</div>
);
}
});
ReactDOM.render(<Name />,document.getElementById('mount-point'));
one state is enough.
var Name = React.createClass({
getInitialState: function () {
return {
inputname: ''
};
},
showName: function (event) {
event.preventDefault();
this.setState({ inputname: this.refs.inputname.value });
},
render: function () {
return (
<div>
<input ref="inputname" placeholder="Enter your name"></input>
<button onClick={this.showName}>Show</button>
<h2>Hello {this.state.inputname}!</h2>
</div>
);
}
});
ReactDOM.render(<Name />, document.getElementById('root'));
you can use refs to get the input value.
I think you want this effect, here is the demo
here is the document of refs more-about-refs

react: get custom checkbox's checked attribute

I want to so some customization with checkbox, it can look like this:
so I wrap my custom checkbox into a React Component:
require('../../less/ck-checkbox.less');
var React = require('react');
var CkCheckbox = React.createClass({
propTypes: {
name: React.PropTypes.string,
text: React.PropTypes.string,
defaultChecked: React.PropTypes.bool,
onChange: React.PropTypes.func
},
getDefaultProps: function() {
return {
name: 'checkbox',
text: '',
defaultChecked: false,
onChange: function () {}
};
},
render: function() {
return (
<div className="ck-checkbox">
<label>
<input
type="checkbox"
name={this.props.name}
ref="c"
defaultChecked={this.props.defaultChecked}
onChange={this.props.onChange.bind(this, this.refs.c.checked)}
/>
<span className="icons">
<span className="icon-checked-o icon-true"></span>
<span className="icon-circle-o icon-false"></span>
</span>
{this.props.text.length > 0 ?
<span className="ck-checkbox-text">{this.props.text}</span> : null
}
</label>
</div>
);
}
});
module.exports = CkCheckbox;
and my container is like this:
var React = require('react');
var CkCheckbox = require('./CkCheckbox.js');
var Test = React.createClass({
render: function() {
return (
<div>
<CkCheckbox onChange={this._handleChange}/>
</div>
);
},
_handleChange: function(checked, e) {
console.log(checked)
}
});
module.exports = Test;
you can see that, I tried to bind this.refs.c.checked in the onChange callback, but it doesn't work.
so, how can I get the checked state of my custom checkbox in Test component in the _handleChange function?
In this case you don't need use refs because you can get checked property from e argument
// CkCheckbox component
<input type="checkbox"
name={this.props.name}
defaultChecked={this.props.defaultChecked}
onChange={ this.props.onChange } />
// Test component
_handleChange: function(e) {
var checked = e.target.checked;
console.log(checked)
}
Example
or if you want pass only checked property you can do it like this
// CkCheckbox component
handleChange: function (e) {
this.props.onChange(e.target.checked);
},
<input type="checkbox"
name={this.props.name}
defaultChecked={this.props.defaultChecked}
onChange={ this.handleChange } />
// in Test component
_handleChange: function(checked) {
console.log(checked)
}
Example
This is a simple example you can use to get the custom value or the value of your checked box, and also to check if the box is checked.
export default class SearchBoxContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
boxAll: false
};
}
handleChange = event => {
this.setState({ boxAll: event.target.checked }, () => {
console.log("This returned true or false", this.state.boxAll);
});
};
render() {
return (
<div className="search-container">
<SearchBox />
<div className="filter-country">
<h1>Filter</h1>
<div className="filter-country-container">
<div>
<input
type="checkbox"
id="checkBoxUS"
name="US"
value="US"
onChange={this.handleChange}
/>
<label htmlFor="US">All Jobs</label>
</div>
</div>
</div>
</div>
);
}
}
It is important to know that in this example, I used the "setState()" callback just for demonstration purposes, but you can pass the value to other components by props or wherever method you prefer. Also, when the checkbox is checked the value will return "true"

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>
);
}
});

react state bind from child to parent element

I am new to reactJS
I have an JSON array which consists of task. I have rendered the the array to 2 ul list. One has completed tasks and the other has uncompleted tasks. If i click on the task the status is changing but it is not updated in other element. However if I enter some text in the input state is set to other elements. Why the state is not set immediately when I click on task?
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/JSXTransformer.js"></script>
<body>
<div id="todo">
</div>
<script type="text/jsx">
var TodoList = React.createClass({
clickHandle: function(index) {
this.props.items[index].completed=!this.props.items[index].completed;
console.log(this.props);
this.setState({items: this.props.items});
},
render: function() {
var createItem = function(itemText, index) {
if(itemText.completed===this.props.completed)
return <li key={index} onClick={this.clickHandle.bind(this,index)}>{itemText.text}</li>;
};
return <ul>{this.props.items.map(createItem, this)}</ul>;
}
});
var TodoApp = React.createClass({
getInitialState: function() {
return {items: [{"text":"1true","completed":true},{"text":"2true","completed":true},{"text":"1false","completed":false}], text: ''};
},
onChange: function(e) {
this.setState({text: e.target.value});
},
handleSubmit: function(e) {
e.preventDefault();
if(this.state.text!=''){
this.state.items.push({"text":this.state.text,"completed":false});
var nextText = '';
this.setState({items:this.state.items,text: nextText});
}
else{
alert("Enter some text!");
}
},
render: function() {
return (
<div>
<h3>TODO</h3>
<TodoList items={this.state.items} completed={false}/>
<TodoList items={this.state.items} completed={true}/>
<form onSubmit={this.handleSubmit}>
<input onChange={this.onChange} value={this.state.text} />
<button>{'Add #' + (this.state.items.length + 1)}</button>
</form>
</div>
);
}
});
React.render(<TodoApp />, document.getElementById('todo'));
</script>
JSFiddle
This is happening because the parent component, TodoApp which renders the two lists does not know that something has changed in one of the them. For this the child component should notify the parent component about it.
Add a onStatusUpdate attribute to TodoList like this
<TodoList items={this.state.items} completed={false} onStatusUpdate={this.update}/>
This is how the update method can be defined
update: function(items){
this.setState({items: items});
}
In the click handler of child component do something like this
clickHandle: function(index {
this.props.items[index].completed=!this.props.items[index].completed;
this.props.onStatusUpdate(this.props.items); // <-- this triggers the onStatusUpdate attribute defined in TodoList component
},
Here is an updated demo https://jsfiddle.net/dhirajbodicherla/aqqcg1sa/2/`

ReactJS: onClick change element

I've just started learning React and have a question.
I want to do the following:
If a user clicks on a paragraph I want to change the element to an input field that has the contents of the paragraph prefilled.
(The end goal is direct editing if the user has certain privileges)
I'm come this far but am totally at a loss.
var AppHeader = React.createClass({
editSlogan : function(){
return (
<input type="text" value={this.props.slogan} onChange={this.saveEdit}/>
)
},
saveEdit : function(){
// ajax to server
},
render: function(){
return (
<header>
<div className="container-fluid">
<div className="row">
<div className="col-md-12">
<h1>{this.props.name}</h1>
<p onClick={this.editSlogan}>{this.props.slogan}</p>
</div>
</div>
</div>
</header>
);
}
});
How can I override the render from the editSlogan function?
If I understand your questions correctly, you want to render a different element in case of an "onClick" event.
This is a great use case for react states.
Take the following example
React.createClass({
getInitialState : function() {
return { showMe : false };
},
onClick : function() {
this.setState({ showMe : true} );
},
render : function() {
if(this.state.showMe) {
return (<div> one div </div>);
} else {
return (<a onClick={this.onClick}> press me </a>);
}
}
})
This will change the components state, and makes React render the div instead of the a-tag. When a components state is altered(using the setState method), React calculates if it needs to rerender itself, and in that case, which parts of the component it needs to rerender.
More about states
https://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html
You can solve it a little bit more clear way:
class EditableLabel extends React.Component {
constructor(props) {
super(props);
this.state = {
text: props.value,
editing: false
};
this.initEditor();
this.edit = this.edit.bind(this);
this.save = this.save.bind(this);
}
initEditor() {
this.editor = <input type="text" defaultValue={this.state.text} onKeyPress={(event) => {
const key = event.which || event.keyCode;
if (key === 13) { //enter key
this.save(event.target.value)
}
}} autoFocus={true}/>;
}
edit() {
this.setState({
text: this.state.text,
editing: true
})
};
save(value) {
this.setState({
text: value,
editing: false
})
};
componentDidUpdate() {
this.initEditor();
}
render() {
return this.state.editing ?
this.editor
: <p onClick={this.edit}>{this.state.text}</p>
}
}
//and use it like <EditableLabel value={"any external value"}/>;

Categories

Resources