Reactjs checkbox cannot be checked - javascript

I have this code in Reactjs that display a label with a checkbox
import React, { Component, PropTypes } from 'react';
class Test extends Component {
constructor() {
super(...arguments);
}
checkboxClicked(e) {
this.props.test.clicked = e.target.checked;
}
render() {
return (
<li>
<label>
<input type="checkbox" value={this.props.test.id} checked={this.props.test.clicked} onChange={this.checkboxClicked.bind(this)} />
{this.props.test.text}
</label>
</li>
);
}
}
export default Test;
The checkbox and text is well displayed, but when I click on it, it refused to get checked. The value of this.props.test.clicked is changed but not the ui in the browser.
Can somebody tell me that I am missing?

It's not recommended to change props.
Try to use state instead.
import React, { Component, PropTypes } from 'react';
class Test extends Component {
constructor() {
super(...arguments);
this.state = { checked: this.props.test.clicked };
}
checkboxClicked(e) {
this.setState({checked : e.target.checked});
}
render() {
return (
<li>
<label>
<input type="checkbox" value={this.props.test.id} checked={this.state.checked} onChange={this.checkboxClicked.bind(this)} />
{this.props.test.text}
</label>
</li>
);
}
}
export default Test;

Related

How to get label values dynamically and adding the numbers together from different input with reactjs

Created a Div and inside it I have label element and input element, I want to get different label values in each div. How to re-use my div component
instead of coding the same code again.
I have tried to search in Stackoverflow plus googles, Haven't received a better answer.
Here I have created div element with just label and input element and then I have rendured this component in App.js file:
How can I reuse the same code/component to create 2 more div and having different labels values in it? Ho can I add numbers together from different input ( which I am getting from different components input)
Appreciate all your help!
import React, { Component } from 'react';
import './calculator.css';
class Boxes extends Component {
state = {
inputOne: '',
inputtwo: '',
inputthree: ''
}
getInputValue = (e) => {
const value = e.target.value;
console.log('value: ', value);
this.setState({
inputOne: Number(e.target.value)
});
}
render() {
const { value } = this.props // destructuring
const {inputOne, inputtwo, inputthree } = this.state
return (
<div className="boxes">
<label className="boxeslevel" htmlFor="text">
{value}
</label>
<input
name="text"
type="text"
onChange={this.getInputValue}
/>
</div>
);
}
}
export default Boxes;
import React, { Component } from 'react';
import './App.css';
import Boxes from './components/calculator';
class App extends Component {
render(){
return (
<div className="wrapper">
<Boxes value= {"Value 1:"} onChange={this.props.onChange}/>
<Boxes value= {"Value 2:"} onChange={this.props.onChange}/>
<Boxes value= {"Value 3:"} onChange={this.props.onChange}/>
<ShowResult />
</div>
);
}
}
export default App;
You should pass a prop to your componente to be reuse. As you notice you are using local component state in your component, like const {value} = this.state try the same approach but with props like const {value} = this.props and then passing that prop in the component usage like
<Boxes value={“label 1”}/>
<Boxes value={“label 2”}/>
That would work. Hope it help you
Remember you can use as many props you need and access them as the same way mention above
You can do something like this:
class Boxes extends Component {
render() {
const { value } = this.props // value coming from props
return (
<div className="wrapper">
<div className="firstBox">
<label htmlFor="text">
{value}
</label>
<input name="text" type="text" />
</div>
</div >
);
}
}
export default Boxes;
and in your app component something like this:
import React, { Component } from 'react';
import './App.css';
import Boxes from './components/calculator';
class App extends Component {
render(){
return (
<div className="App">
<Boxes value={1}/>
<Boxes value={2}/>
<Boxes value={3}/>
</div>
);
}
}
export default App;
Here is live demo link
You have to use props instead of state in your Boxes component. Then you can pass the required props from the App component.
App.js
import React, { Component } from 'react';
import './App.css';
import Boxes from './components/calculator';
class App extends Component {
render(){
return (
<div className="App">
<Boxes value={"Value 1"}/>
<Boxes value={"Value 2"}/>
<Boxes value={"Value 3"}/>
</div>
);
}
}
export default App;
Boxes.js
import React, { Component } from 'react';
import './calculator.css';
class Boxes extends Component {
render() {
const { value } = this.props // destructuring
return (
<div className="wrapper">
<div className="firstBox">
<label htmlFor="text">
{value}
</label>
<input name="text" type="text" />
</div>
</div >
);
}
}
export default Boxes;

Handle <select> component change in a ReactJS form

ReactJS n00b, trying to build a simple, reusable < select > component in ReactJS with an onClick callback. I'm not getting any console or webpack errors, but nothing is happening when I change the selected option.
Caster.js
import React from 'react';
import ReactDOM from 'react-dom';
import { SelectSchool } from './SelectSchool';
import { Button } from './Button';
export class Caster extends React.Component {
constructor(props) {
super(props);
...
this.handleChange = this.handleChange.bind(this);
this.handleClick = this.handleClick.bind(this);
}
handleChange(e){
console.log('handleChange'); // TEST - nothing appears in console
var value = e.target.value;
this.setState({casterSchool: value});
this.props.select(value);
console.log('value: ' + value); // TEST - nothing appears in console
}
render() {
return (
<div className="instance-wrap">
<div className="input-row">
<SelectSchool phaseSelect="select-caster" onChange={this.handleChange} />
...
</div>
</div>
);
}
}
SelectSchool.js
import React from 'react';
import ReactDOM from 'react-dom';
export class SelectSchool extends React.Component {
render() {
return (
<div className="input-wrap">
<label>School</label>
<select className={this.props.phaseSelect} value={this.props.value} onChange={this.props.handleChange}>
<option value='alteration'>Alteration</option>
...
<option value='divination'>Divination</option>
</select>
</div>
);
}
}
SelectSchool.defaultProps = { phaseSelect: 'default' };
Any help or advice is greatly appreciated.
The name of the prop that you pass to the <SelectSchool in your example is onChange but inside the component you are trying to access this.props.handleChange (there is no such prop).
You should use this.prop.onChange or pass the handleChange={this.handleChange} to the component.
Option 1:
<select className={this.props.phaseSelect} value={this.props.value} onChange={this.props.onChange}>
Option 2:
<SelectSchool phaseSelect="select-caster" handleChange={this.handleChange} />

How to make/access state using props in react?

I made an app with multiple components and want their state to be accessed using parent/main app, I'm not sure how to get it. what i'm trying to do is when i change state in main "App" the component state should change. One of the component is 'checkbox' and now i want to access its state using parent app, I made multiple attempts but not getting it done. my code goes like this..
This is Main 'App' code:
import React, { Component } from 'react';
import Checkbox from './checkbox';
import Radio from './Radio';
import ToggleSwitch from './ToggleSwitch';
import PrimaryButton from './PrimaryButton';
class App extends Component {
onClick(isClicked){
isChecked:true
};
render() {
return (
<div id="form">
<Checkbox
onClick={this.onClick}
/>
<RadioButton
onClick={this.onClick}
/>
</div>
);
}
}
export default App;
The component i want to access goes like this:
import React, { Component } from 'react';
class Checkbox extends Component {
constructor(props){
super(props);
this.state={
isChecked:true
};
};
onCheck(){
this.setState({
isChecked: !this.state.isChecked
});
this.props.isClicked()
};
render() {
return (
<div>
<div
className={this.state.isChecked ? 'checked': 'unchecked'}
onClick={this.onCheck.bind(this)}
>
</div>
</div>
);
}
}
export default Checkbox;
You forgot to bind the onClick event in the app component, try this it will work :
class App extends Component {
onClick(isClicked){
console.log('isClicked', isClicked);
};
render() {
return (
<div id="form">
<Checkbox onClick={this.onClick.bind(this)}/>
</div>
);
}
}
If you already have onClick handler for the Checkbox I don't see why you couldn't just move the state up to the App component and just pass down a callback from there to the Checkbox that will update the parent state. That seems like a more React way to do it, to me.
class App extends Component {
constructor(props){
super(props);
this.state={
isChecked:true
}
}
onClick = (isClicked) => {
this.setState({isChecked: !this.state.isChecked})
}
render() {
return (
<div id="form">
<Checkbox
onClick={this.onClick}
ischecked={this.state.isChecked}
/>
</div>
);
}
}
Component
class Checkbox extends Component {
onCheck(){
this.props.onClick()
}
render() {
return (
<div>
<div
className={this.props.isChecked ? 'checked': 'unchecked'}
onClick={this.onCheck.bind(this)}
>
</div>
</div>
)
}
}

How to override className on extended component?

I am trying to position this component differently on a certain page. But when I provide it with another className property it is only using the original class's styling that was provided when declaring the component.
Component:
import React, { Component } from 'react';
import styles from './label.css';
class Label extends Component {
render() {
return (
<div className={styles.labelClass} />
);
}
}
export default Label;
Page where I want to position it differently:
import React, { Component } from 'react';
import styles from './page.css';
import Label from '../common/label.jsx';
class Page extends Component {
render() {
return (
<div>
<Label className={styles.positionLeft} />
</div>
);
}
}
export default Page;
Normally I would do this with custom styling but I have to use media
queries so this isn't possible in this situation.
Since <Label> is a custom component, you can to manually pass the className prop down.
This is a good use case for default props!
class Label extends Component {
render() {
return (
<div className={this.props.className} />
);
}
}
Label.defaultProps = {
className: styles.labelClass
}
That way, if no className is provided to Label, it will use the labelClass style, otherwise, it will use the prop.
I fixed it by adding another optional property customClass to the component.
Label
import React, { Component } from 'react';
import styles from './label.css';
class Label extends Component {
render() {
return (
<div className={styles.labelClass + ' ' + this.props.customClass} />
);
}
}
export default Label;
Page
import React, { Component } from 'react';
import styles from './page.css';
import Label from '../common/label.jsx';
class Page extends Component {
render() {
return (
<div>
<Label customClass={styles.positionLeft} />
</div>
);
}
}
export default Page;
You need to explicitly reference the className property from Label's props - try:
import React, { Component } from 'react';
import styles from './label.css';
class Label extends Component {
render() {
let { className } = this.props
if (!className) {
className = styles.labelClass
}
return (
<div className={className} />
);
}
}
export default Label;

Using Meteor with input of checkbox

Hello I have having a problem with my checkbox's staying checked when I check them. So what I want to be able to do is check and uncheck as I click the box. But once I check it it is stuck with a check and I can no longer do anything to it. Here is the relevant code!
import React, {Component} from 'react';
export default class ResolutionSingle extends Component {
toggleChecked() {
Meteor.call('toggleResolution', this.props.resolution._id, this.props.resolution.copmlete);
}
deleteResolution() {
Meteor.call('deleteResolution', this.props.resolution._id);
}
render() {
return (
<li>
<input type="checkbox"
readOnly={true}
checked={this.props.resolution.complete}
onClick={this.toggleChecked.bind(this)} />
{this.props.resolution.text}
<button className="btn-cancel"
onClick={this.deleteResolution.bind(this)}>
×
</button>
</li>
)
}
}
Here are the methods
Meteor.methods({
addResolution(resolution) {
Resolutions.insert({
text: resolution,
complete: false,
createAt: new Date()
});
},
toggleResolution(id, status) {
Resolutions.update(id, {
$set: {complete: !status}
});
},
deleteResolution(id) {
Resolutions.remove(id);
}
});
Here is the main wrapper
import React from 'react';
import ReactDOM from 'react-dom';
import TrackerReact from 'meteor/ultimatejs:tracker-react';
import ResolutionsForm from './ResolutionsForm.jsx';
import ResolutionSingle from './ResolutionSingle.jsx';
Resolutions = new Mongo.Collection("resolutions");
export default class ResolutionsWrapper extends TrackerReact(React.Component) {
constructor(){
super();
this.state = {
subscription: {
resolutions: Meteor.subscribe("allResolutions")
}
}
}
componentWillUnmount() {
this.state.subscription.resolutions.stop();
}
resolutions() {
return Resolutions.find().fetch();
}
render(){
return (
<div>
<h1>My Resolutions</h1>
<ResolutionsForm />
<ul className="resolutions">
{this.resolutions().map( (resolution)=>{
return <ResolutionSingle key={resolution._id} resolution={resolution} />
})}
</ul>
</div>
)
}
}
You have a typo in your code.
Meteor.call('toggleResolution', this.props.resolution._id, this.props.resolution.copmlete);
It should be complete instead of copmlete. In order to avoid errors like that in the future, you can use check functions in your Meteor methods.

Categories

Resources