react: access value of input component - reactjs

I have build an input-field component and need to access its value from parent component. I tried something like document.getelementById(id).value, but it'll return null as value.
Parent component:
import StateBox from './StateBox.js';
import React, { Component } from 'react';
export default class AdressenListe extends Component {
render() {
let filteredAdressen = this.props.adressen.filter(
(asingle) => {
return asingle.Firma.toLowerCase().indexOf(document.getElementById('Firma').value.toLowerCase()) !== -1;
}
);
var anzahl = filteredAdressen.length;
return (
<div>
<StateBox id="Firma" />
<StateBox id="PLZ" />
<li>
</li>
</div>
);
}
}
Input-field component:
import React, {Component} from 'react';
export default class StateBox extends Component {
//constructor input field
constructor() {
super();
//equal to object
this.state = {
search: ''
};
}
updateSearch(event) {
console.log(event.target.value);
this.setState({search: event.target.value});
}
render(){
return(
<form className="StateBox">
<input type="text" value={this.state.search} onChange={this.updateSearch.bind(this)}/>
</form>
);
}
}

You can declare the state in the parent component and pass function to update that in child component
class Parent extends Component {
this.state = {
value: ''
}
changeValue = (value) => {
this.setState({value});
}
render() {
return <Child inputValue={this.state.value} changeValue={this.state.changeValue} />
}
}
class Child extends Component {
render() {
<input value={this.props.inputValue} onChange={(e) => this.props.changeValue(e.target.value)} />
}
}

If you want to access the value of a child component, you need to lift the state up and make the child component controlled, because that's the way you should code in react.
Taking your code as base:
class AdressenListe extends Component {
constructor() {
super();
this.state = {
Firma: ''
};
}
changeValue (Firma) {
this.setState({Firma});
}
render() {
let filteredAdressen = this.props.adressen.filter(
(asingle) => {
return asingle.Firma.toLowerCase().indexOf(this.state.Firma.toLowerCase()) !== -1;
}
);
return (
<div>
<StateBox inputValue={this.state.Firma} changeValue={this.changeValue.bind(this)} />
</div>
);
}
}
Note how I pass down the necessary props and the state is managed by the parent.
class StateBox extends Component {
render () {
return <input type="text" value={this.props.inputValue} onChange={(e) => this.props.changeValue(e.target.value)} />
}
}

Related

React: Props are not being passed to children

So I have this parent which clone and injects props Login to the children:
import React, { Component } from 'react';
import { Container } from 'reactstrap';
import { NavMenu } from '../navigations/NavMenu';
import { Login } from './account/Login';
export class Layout extends Component {
static displayName = Layout.name;
render() {
const loginForm = new Login();
const childrenWithProps = React.Children.map(this.props.children, child => {
if (React.isValidElement(child)) {
return React.cloneElement(child, { loginForm: loginForm });
}
return child;
});
return (
<div>
{loginForm.render()}
<NavMenu />
<Container>
{childrenWithProps}
</Container>
</div>
);
}
}
This is one of the children:
import React, { Component } from 'react';
import { http } from '../../helpers/Http';
export class FetchData extends Component {
static displayName = FetchData.name;
constructor(props) {
super(props);
this.state = { forecasts: [], loading: true };
let x = this.props.loginForm; <-- THIS IS UNDEFINED
}
.......
}
The this.props.loginForm is undefined. How can I inject props correctly?
EDIT
This is the Login component:
import React, { Component } from 'react';
import './Login.css';
export class Login extends Component {
constructor(props) {
super(props);
this.state = { show: false };
this.login = this.login.bind(this);
this.showLogin = this.showLogin.bind(this);
}
showLogin() {
this.setState({
show: true
});
}
login() {
}
render() {
return (
<form className={this.state.show ? "login-form " : "login-form hide"} onSubmit={this.login()}>
<h1>Login</h1>
<div className="form-group">
<input required type="text" placeholder="Email" />
<input required type="password" placeholder="Password" />
</div>
<button type="submit" className="btn btn-primary">Login</button>
</form>
);
}
}
I want to call showLogin() from FetchData. If the user is not authorized when fetching the data, I want to show the login modal.

passing state of child component

So I have a component "itemSelection" and inside of it I map through an api response like this
<div className="row">
{this.state.items.map(i => <Item name={i.name} quantity={i.quantity} />)}
</div>
Here the state of "Item" component
constructor(props){
super(props);
this.state = {
visible: false,
selected: false,
}
}
How could I pass the state of "Item" component to "itemSelection" component?
Sending data back up to your parent component should be done by using props.
Fairly common question, see this post for the long answer.
As according to me, If I understood your question you want to call the state of the child component to the parent component.
//Child.js
import s from './Child.css';
class Child extends Component {
getAlert() {
alert('clicked');
}
render() {
return (
<h1 ref="hello">Hello</h1>
);
}
}
export default withStyles(s)(Child);
//Parent.js
class Parent extends Component {
render() {
onClick() {
this.refs.child.getAlert()
}
return (
<div>
<Child ref="child" />
<button onClick={this.onClick.bind(this)}>Click</button>
</div>
);
}
}
Also, you can get the code reference from the link: https://github.com/kriasoft/react-starter-kit/issues/909
This a little tricky but Maybe, its help you solving your problem.
//Parent.js
class Parent extends Component {
component(props) {
super(props)
this.state = {
test: 'abc'
}
}
ParentFunction = (value) => {
this.state.test = value;
this.setState(this.state);
}
render() {
return (
<div>
<Child
test={this.state.test}
ParentFunction={this.ParentFunction}
/>
</div>
);
}
}
//Child.js
import s from './Child.css';
class Child extends Component {
component(props) {
super(props)
this.state = {
test: props.test
}
}
handleChange = () => {
this.state.test = event.target.value;
this.setState(this.state);
this.handleOnSave()
}
handleOnSave = () => {
this.props.ParentFunction(this.state.test);
}
render() {
return (
<div>
<input type="text" onChange={this.handleChange} />
</div>
);
}
}
export default withStyles(s)(Child);

Take input in a child component and output it in another child component in Reactjs

In Reactjs if I have two child components of an App component, can I take input from one component and output it in the other child component?
class App extends Component{
render(
<Input/>
<Output/>
)
}
Input = () => { //input }
Output = () => { //output }
It's simple. Use the same state value for both components in the parent component:
class App extends Component{
constructor(props){
super(props);
this.state = {
value: ''
}
onValueChange = thisonValueChange.bind(this);
}
onValueChange(e) {
e.preventDefault();
setState({
value: e.target.value
});
}
render(){
return(
<Input value={this.state.value} onChange={this.onValueChange} />
<Output value={this.state.value}/>
);
}
}
Input = (props) => {
<input value={props.value} onChange={props.onValueChange}>
}
Output = (props) => <div>{props.value}</div>);
You can handle the data in the App component via state by passing a handler down to the Input component
and then pass the state value down to the Output component like
const Input = props => <input onChange={props.handleChange} />
const Output = props => <span>{props.data}</span>
class App extends Component {
state = {data:""}
handleChange = e => {
this.setState({ data: e.target.value })
}
render() {
return (
<div>
<Input handleChange={this.handleChange} />
<Output data={this.state.data} />
</div>
)
}
}
`export class Parent extends React.Component{
constructor(props){
super(props);
this.state={
name:'',
sendData:false
}
}
render(){
return (<div><input type="text" onChange={(event)=>
{this.setState({
name:event.target.value,
})
})
/>
//sendData can be made true on a button click
{this.state.sendData ?(<div><Child name={this.state.name}
/>
</div>):null}
</div>)}
}`
Display the data of Parent in the child component.
`export class Child extends React.Component{
render(){
return (<div>Name is :{this.props.name}</div>)
}
}`

React: Using Child checkbox to update Parent component's state

I have the following Parent component:
export class Parent extends Component {
constructor(props) {
super(props)
state = {
value: 0
}
}
}
render() {
return (
<Child />
)
}
And the following Child component:
export class Parent extends Component {
constructor(props) {
super(props)
state = {
num: 0
}
}
}
toggleCheckboxChange = () => {
this.setState({ num: 5})
}
render() {
return (
<div>
<label>
{this.state.num}
<input type="checkbox" onChange={this.toggleCheckboxChange}
/>
</label>
</div>
)
}
I want to use the checkbox to set the Child state num to 5, and then pass that to the Parent's state value.
What would be the best way of doing that?
As I said in my comment, it's easiest if you move the state into the parent.
working example
import React, {Component} from 'react';
import {render} from 'react-dom';
class Parent extends Component {
state = {
value: 0
}
toggleCheckboxChange = ev => {
this.setState({value: 5})
}
render() {
return (
<Child num={this.state.value} toggleCheckboxChange={this.toggleCheckboxChange}/>
);
}
}
function Child({num, toggleCheckboxChange}) {
return (
<div>
<label>
{num}
<input type="checkbox" onChange={toggleCheckboxChange}
/>
</label>
</div>
)
}
render(<Parent/>, document.getElementById('root'));

How to make dependence between two form filters in ReactJS

I have three classes in my ReactJS app. Here they are :
class FirstFilter extends React.Component {
constructor() {
super();
this.state = {
val1: ''
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
render() {
return (
<Label>
<Input type="select" value={this.state.value} onChange={this.props.handleChange}>
<option disabled selected value>Select plox</option>
<option value='Firdt'>First</option>
<option value='Second'>Second</option>
</Input>
</Label>
);
}
}
class SecondFilter extends React.Component {
constructor() {
super();
this.state = {
val2: ''
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({value: event.target.val2});
}
render() {
return (
<Label>
<Input type="search" placeholder="Print somthing" value={this.state.value} onChange={this.props.handleChange}>
</Input>
</Label>
);
}
}
class Main extends React.Component {
constructor() {
super();
this.state = {
val1: '',
val2: ''
};
this.handleChangeVal1 = this.handleChangeVal1.bind(this);
this.handleChangeVal2 = this.handleChangeVal2.bind(this);
}
handleChangeUUID(event) {
this.setState({val1: event.target.value.toLowerCase()});
}
handleChangeOrigin(event) {
this.setState({val2: event.target.value.toLowerCase()});
}
render() {
return (
<div>
<Form inline>
<FormGroup>
<div>
<UuidRow handleChange = {this.handleChangeVal1} />
</div>
<div>
<OriginRow handleChange = {this.handleChangeVal2} />
</div>
</FormGroup>
</Form>
</div>
);
}
}
I want make SearchField from second filter empty when i check whatever in my DropDownList from first filter. When i only change value in my Main it's still leave typed text there. Maybe I doing something wrong and didn't understand basic hierarchy?
You should pass props to your child component, SearchField, when the state of the parent, Main, has been updated by the callback invoked by the DropDownList. The code in your example isn't consistent, so I can't guess what I need to change to help you, but here is a very basic example of how setting state in the parent via a callback event handler passed to one child (text input) can be used to set props on the second child (text area):
https://codesandbox.io/s/BLwl1y6j2
main.js
import React, { Component } from 'react';
import { render } from 'react-dom';
import FirstChild from './FirstChild';
import SecondChild from './SecondChild';
class Main extends Component {
constructor(props) {
super(props);
this.state = {
val1: '',
};
}
// callback to pass as prop to child element text input
handleChangeVal1 = (event) => {
// sets parent state
this.setState({val1: event.target.value.toLowerCase()});
}
render() {
return (
<div>
<FirstChild handleChange = { this.handleChangeVal1 } value={ this.state.val1 }/>
<SecondChild value={ this.state.val1 }/>
</div>
);
}
}
render(<Main />, document.getElementById('root'));
FirstChild.js
import React, {Component } from 'react';
class FirstChild extends Component {
// input calls handleChange callback passed in props to modify parent component state
render() {
console.log(this.props.value);
return (
<input type="text" value={this.props.value} onChange={this.props.handleChange}/>
);
}
}
export default FirstChild;
SecondChild.js
import React, { Component } from 'react';
class SecondChild extends Component {
// render text area with value passed in props
render() {
console.log(this.props.value);
return (
<textarea value={this.props.value} onChange={this.props.handleChange}/>
);
}
}
export default SecondChild;

Resources