I have this checkbox example
constructor(props) {
super(props);
this.state = {
check: true,
};}
checkBoxtTest(){
this.setState(
{check:!this.state.check})}
on return
<CheckBox
value={this.state.check} onChangee={()=>this.checkBoxtTest()}
/>
when i press again in checkbox the value doesn't change
you are having a typo 'onChange'
<CheckBox
value={this.state.check} onChange={()=>this.checkBoxtTest()}
/>
If you are using state for changing state follow this way
this.setState((prevState) => ({check: !prevState.check}))
You can use arrow function instead of normal function
checkBoxtTest = () => {
this.setState((prevState) => ({check: !prevState.check}));
}
import React, { Component } from 'react';
import { Container, Content, ListItem, CheckBox, Text, Body } from 'native-base';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
checked: true
}
}
render() {
return (
<Container>
<Content>
<ListItem>
<CheckBox
checked={this.state.checked}
onPress={() => this.setState({checked: !this.state.checked})}
/>
<Body>
<Text>Finish list Screen</Text>
</Body>
</ListItem>
</Content>
</Container>
);
}
}
Firstly,change it to onChange.And your checkBoxTest should be bind in the constructor as it is recommended as best practice.
constructor(props) {
super(props);
this.state = {
check: true,
};
this.checkBoxtTest = this.checkBoxtTest.bind(this);
}
checkBoxtTest(){
this.setState({
check : !this.state.check
})
}
<CheckBox value={this.state.check} onChange={this.checkBoxtTest()} />
Related
I'm relatively new to react & can't seem to figure it out, I have researched this for sometime now & nothing seems to work.
I have a parent component where I'm using createRef
class Parent extends React.Component {
constructor(props) {
super(props);
this.chartRef = React.createRef();
}
Then pass it to child & access is like following
<Grid item xs={12}>
<Child
ref={this.chartRef}
/>
<Button onClick={this.getState}> get ref info</Button>
</Grid>
But in getState chartRef current is always null
getState = () => {
console.log(this.chartRef.current);
};
Here is the child component
class Child extends React.Component {
componentDidMount() {
this.props.registerPlugins.forEach(plugin => {
Chart.pluginService.register(plugin);
});
}
render = () => {
const { data, options, plugins, height } = this.props;
const updatedOptions = {
...options
};
return <div>
<Line
height={height}
data={data}
options={updatedOptions}
plugins={plugins}/>
</div>;
};
}
Child.propTypes = {
height: PropTypes.number.isRequired,
data: PropTypes.object.isRequired,
options: PropTypes.object.isRequired,
plugins: PropTypes.array,
registerPlugins: PropTypes.array,
};
export default Child;
Any help is appreciated
You could use the callback style ref E.g.instead of passing your ref as the prop, you can pass in a reference to a function like this.handleRef
handleRef = r => {
this.chartRef.current = r;
};
<Child ref={this.handleRef} />
You can access child component in parent with help of reference as like below
import React from "react";
import { Button, View } from "react-native";
import Child from "./Child";
class App extends React.Component {
constructor() {
super();
this.chartRef = React.createRef();
}
render() {
return (
<View>
<Child ref={(r) => (this.chartRef = r)} />
<Button
title="Parent Button"
onPress={() => {
console.log(this.chartRef);
}}
></Button>
</View>
);
}
}
export default App;
// Child.js
import React from "react";
import { Button } from "react-native";
export default class Child extends React.Component {
constructor() {
super();
}
render() {
return (
<Button
title="Child Button"
onPress={() => {
alert("Child");
}}
></Button>
);
}
}
you can try this code on codesandbox example
So I am quite new to React world, and I have this problem I am trying to solve, but I don't quite understand why it is happening.
So I want to pass the state of component to parent component and from parent component to child component and everything look okay, and in console log the state goes trough, but nothing changes. I believe there is a way I need to listen for state change or something within child component so it works. If I put true in the parent component, child component also get's true, but if I toggle it on click, it goes trough but nothing changes in the child component.
Also I understand my code is little rough right now ill reafactor it later, but right now I am trying to understand why it does not work.
If anyone could help me I would be thankful for it.
This is component that controls the state.. So the state passes from TurnOnBtn to App and from App it goes to TodoList
import "./Todo.css";
class TurnOnBtn extends Component {
constructor(props) {
super(props);
this.state = { display: false };
this.handleState = this.handleState.bind(this);
}
handleState() {
this.setState({ display: !this.state.display });
this.props.checkDisplay(this.state.display);
}
render() {
return (
<button onClick={this.handleState} className="TurnOnBtn">
<i className="fa fa-power-off"></i>
</button>
);
}
}
export default TurnOnBtn;
parent component App
import TurnOnBtn from "./TurnOnBtn";
import TheMatrix from "./TheMatrxHasYou";
import TodoList from "./TodoList";
import { Component } from "react";
class App extends Component {
constructor(props) {
super(props);
this.state = { display: true };
this.checkDisplay = this.checkDisplay.bind(this);
}
checkDisplay(newDisplay) {
this.setState({
display: newDisplay,
});
console.log(this.state);
}
render() {
return (
<div className="App">
<TodoList display={this.state.display} />
<TheMatrix />
<TurnOnBtn checkDisplay={this.checkDisplay} />
</div>
);
}
}
export default App;
child component TodoList
import Todo from "./Todo";
import NewTodoForm from "./NewTodoForm";
import { v4 as uuid } from "uuid";
import "./Todo.css";
class TodoList extends Component {
constructor(props) {
super(props);
this.state = {
todos: [],
displayOn: this.props.display,
};
this.newTodo = this.newTodo.bind(this);
this.editTodo = this.editTodo.bind(this);
this.deleteTodo = this.deleteTodo.bind(this);
}
editTodo(id, updatedTask) {
const updatedTodo = this.state.todos.map((todo) => {
if (todo.id === id) {
return { ...todo, todo: updatedTask };
}
return todo;
});
this.setState({
todos: updatedTodo,
});
console.log(updatedTask);
}
deleteTodo(id) {
this.setState({
todos: this.state.todos.filter((todo) => todo.id !== id),
});
}
newTodo(newState) {
this.setState({
todos: [...this.state.todos, { ...newState }],
});
}
render() {
return (
<div
style={this.state.displayOn ? { opacity: 1 } : { opacity: 0 }}
className="Todo-screen"
>
{" "}
<div className="TodoList">
<div className="TodoList-todos">
{" "}
{this.state.todos.map((todo) => (
<Todo
key={uuid()}
id={todo.id}
active={todo.active}
editTodo={this.editTodo}
deleteTodo={this.deleteTodo}
todoItem={todo.todo}
/>
))}
</div>
</div>{" "}
<NewTodoForm newTodo={this.newTodo} />
</div>
);
}
}
export default TodoList;
The bug here is in these line of codes:
handleState() {
this.setState({ display: !this.state.display });
this.props.checkDisplay(this.state.display);
}
Remember setState is an async function, so by the time you set a new state using setState, the value for this.state is not guaranteed changed.
One way to fix this is using the setState callback, which will run after the state is changed:
handleState() {
this.setState({ display: !this.state.display }, function() {
this.props.checkDisplay(this.state.display);
});
}
But you don't need to use another state to keep display state in TurnOnBtn as you can pass the toggle callback from the parent:
App.js
class App extends Component {
constructor(props) {
super(props);
this.state = { display: true };
this.toggleDisplay = this.toggleDisplay.bind(this);
}
toggleDisplay() {
this.setState({
display: !this.state.display,
});
}
render() {
return (
<div className="App">
<TodoList display={this.state.display} />
<TheMatrix />
<TurnOnBtn toggleDisplay={this.toggleDisplay} />
</div>
);
}
}
TurnOnBtn.js
class TurnOnBtn extends Component {
constructor(props) {
super(props);
this.handleState = this.handleState.bind(this);
}
handleState() {
this.props.toggleDisplay();
}
render() {
return (
<button onClick={this.handleState} className="TurnOnBtn">
<i className="fa fa-power-off"></i>
</button>
);
}
}
The popup show up after 1 sec. But I need to show it only to user who doesn't subscribe yet, by using localStorage. I did try use local storage like this code below, but then all I've got is a blank white page when it's time to show/not show popup. Is the localStorage I coded was totally wrong? Please help
import React from 'react'
import styled from 'react-emotion'
import Rodal from 'rodal'
import '../styles/rodal.css'
import Delayed from '../components/Delayed'
const Signup = () => (
<Containers>
<SubsribtionForm
action="https://subscribe/post?/....."
method="post"
>
<SubscribeInput type="email" name="EMAIL" placeholder="Subscribe to Updates!" required />
<Button type="submit" onClick={this.submit}>Add Me</Button>
</SubsribtionForm>
</Containers>
)
export default class Popup extends React.Component {
constructor(props) {
super(props)
this.state = { visible: true }
if (localStorage.getItem('submit')) {
this.setState({ visible: false })
}
this.submits = this.submits.bind(this)
}
submits() {
const newsub = this.state.submit
localStorage.setItem('submit', newsub)
}
show() {
this.setState({ visible: true })
}
hide() {
this.setState({ visible: false })
}
render() {
return (
<div>
<Container>
<Delayed waitBeforeShow={1000}>
<Rodal
visible={this.state.visible}
onClose={this.hide.bind(this)}
width={500}
height="100%"
customStyles={customStyles}
>
<Box>
<Banner />
<ContainerContent>
<Header>Subscribe to our mailing list</Header>
<Words>
We will organize and send regular updates Stay informed!
</Words>
</ContainerContent>
<ContainerForm>
<Signup />
</ContainerForm>
</Box>
</Rodal>
</Delayed>
</Container>
</div>
)
}
}
constructor(props) {
super(props)
this.state = {
visible: !(localStorage.getItem('submit') !== '' && localStorage.getItem('submit') !== null),
}
this.submits = this.submits.bind(this)
}
Just check if submit is not empty, like above.
Another approach would be to do the following in componentDidMount life cycle
componentDidMount() {
if (localStorage.getItem('submit')) {
this.setState({ visible: false })
}
}
You are calling this.setState inside the class constructor, you can use a simple conditional in this.state to assign the value directly and please use the bind in the constructor :D. I use the length because if the string is '' the length is 0 then that value in the conditional is false
import React from 'react'
import styled from 'react-emotion'
import Rodal from 'rodal'
import '../styles/rodal.css'
import Delayed from '../components/Delayed'
const Signup = () => (
<Containers>
<SubsribtionForm
action="https://subscribe/post?/....."
method="post"
>
<SubscribeInput type="email" name="EMAIL" placeholder="Subscribe to Updates!" required />
<Button type="submit" onClick={this.submit}>Add Me</Button>
</SubsribtionForm>
</Containers>
)
export default class Popup extends React.Component {
constructor(props) {
super(props)
const submit = localStorage.getItem('submit')
this.state = { visible: !submit && !submit.length }
this.submits = this.submits.bind(this)
this.show = this.show.bind(this)
this.hide = this.hide.bind(this)
}
submits() {
const newsub = this.state.submit
localStorage.setItem('submit', newsub)
}
show() {
this.setState({ visible: true })
}
hide() {
this.setState({ visible: false })
}
render() {
return (
<div>
<Container>
<Delayed waitBeforeShow={1000}>
<Rodal
visible={this.state.visible}
onClose={this.hide}
width={500}
height="100%"
customStyles={customStyles}
>
<Box>
<Banner />
<ContainerContent>
<Header>Subscribe to our mailing list</Header>
<Words>
We will organize and send regular updates Stay informed!
</Words>
</ContainerContent>
<ContainerForm>
<Signup />
</ContainerForm>
</Box>
</Rodal>
</Delayed>
</Container>
</div>
)
}
}
Can I use children in React Container or is it wrong?
For example, I have a list of buttons(ActionButton) that are grouped together (ActionMenu).
import React from 'react';
class App extends React.Component {
render() {
return (
<ActionMenu>
<ActionButton name="New" icon="add" />
<ActionButton name="Delete" icon="remove" />
</ActionMenu>
)
}
}
class ActionMenu extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
alert('Click!');
}
render() {
return React.Children.map(this.props.children, (button) =>
React.cloneElement(button, {
onClick: this.handleClick
})
);
}
}
function ActionButton({ name, icon, onClick }) {
return <button class={icon} onClick={onClick}>{name}</button>
}
You can use children regardless of whether it's a component of container.
"[children are] especially common for components like Sidebar or Dialog that represent generic 'boxes'."
In your case you have a menu, which falls into this category.
https://reactjs.org/docs/composition-vs-inheritance.html
I think this is what you are after. Actually you should just put the children in its closest parent instead of its grandpa.
import React from 'react';
import { render } from 'react-dom';
function ActionButton({ name, handleClick }) {
return <button onClick={handleClick}>{name}</button>
}
class ActionMenu extends React.Component {
constructor(props) {
super(props);
}
handleClick = () => {
alert('Click!');
}
render() {
return (
<div>
<ActionButton name="add" handleClick={this.handleClick}/>
<ActionButton name="remove" handleClick={this.handleClick} />
</div>
);
}
}
class App extends React.Component {
render() {
return (
<ActionMenu />
)
}
}
render(<App />, document.getElementById('root'));
You can try to run it in sandbox.
By the way, using bind is quite redundant now, we can use public class fields syntax, which is already ECMA stage 2.
How do I get the value of radio buttons , if I call updateRadioButton in RadioGroup, it results in error. I need to print as Male or Female in console using (react-radio-buttons). Radio Buttons are printing correctly but I'm unable to get the value. Thank you in Advance.
class CreateUserComponent extends React.Component {
constructor(props) {
super(props);
this.state={radio:''}
}
updateRadioButton(e) {
this.setState({ radio: e.target.value });
}
<RadioGroup horizontal>
<RadioButton value="Male">Male</RadioButton>
<RadioButton value="Female">Female</RadioButton>
</RadioGroup>
Well according to the DOCS of this lib, RadioGroup has a onChange prop handler that you can pass that will return the selected value, and then you could set it in the state or pass it on.
Here is small running example with your code:
debugger
const RadioGroup = ReactRadioButtonsGroup.ReactRadioButtonsGroup;
const RadioButton = ReactRadioButtonsGroup.ReactRadioButton;
class App extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
onRadiochange = value => {
console.log(value);
};
render() {
return (
<div>
<RadioGroup horizontal onChange={this.onRadiochange}>
<RadioButton value="Male">Male</RadioButton>
<RadioButton value="Female">Female</RadioButton>
</RadioGroup>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/react-radio-buttons-group#1.0.2/build/bundle.min.js"></script>
<div id="root"></div>
From this react-radio-buttons example:
class CreateUserComponent extends React.Component {
...
updateRadioButton(value) {
this.setState({ radio: value });
}
render() {
...
return (
<RadioGroup horizontal onChange={this.updateRadioButton} >
<RadioButton value="Male">Male</RadioButton>
<RadioButton value="Female">Female</RadioButton>
</RadioGroup>
)
...
}
}
Add onChange event to RadioGroup.
class CreateUserComponent extends React.Component {
constructor(props) {
super(props);
this.state={radio:''};
this.updateRadioButton = this.updateRadioButton.bind(this);
}
updateRadioButton(value) {
this.setState({ radio: value });
}
render() {
return(
<RadioGroup horizontal onChange={this.updateRadioButton}>
<RadioButton value="Male">Male</RadioButton>
<RadioButton value="Female">Female</RadioButton>
</RadioGroup>
);
}