react-router - how change the url - reactjs

I need to have the user edit the url the "path" appears in the input of the other component and when searching the input change the url in real time. How can I use "withRouter" to perform this function?
// App.js component
class App extends Component {
render() {
const { match, location, history } = this.props;
return (
<div >
<Search
searchString={location.pathname}
/>
</div>
)
}
}
export default withRouter(App)
//Search.js component
const Search = ({ searchString }) => (
<div>
<input
value={searchString}
type="search"
placeholder="Search"
aria-label="Search"
/>
</div>
)

This should work for you although I'm not sure redirecting user to another page while typing into search input is a good UX.
// App.js component
class App extends Component {
state = {
searchString: this.props.location.pathname
}
handleSearch = (event) => {
this.setState(
{ searchString: event.target.value },
() => this.props.history.push('/search?query=' + this.state.searchString)
);
}
render() {
return (
<div >
<Search
onChange={this.handleSearch}
searchString={this.state.searchString}
/>
</div>
)
}
}
export default withRouter(App)
const Search = ({ searchString, onChange }) => (
<div>
<input
onChange={onChange}
value={searchString}
type="search"
placeholder="Search"
aria-label="Search"
/>
</div>
)

Related

pass input data from one component to another component in react js?

I am new to learning React.
I wanted to make it: when entering data into the input, this data automatically appear in H1in another component.
Screen.js
class Screen extends React.Component {
render() {
return (
<div className="screen">
<h1>Text from input</h1>
</div>
);
}
}
export default Screen;
Inputs.js
class Inputs extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('Value: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<input type="text" value={this.state.value} onChange={this.handleChange} />
<input type="submit" value="Enter" />
</form>
);
}
}
export default Inputs;
App.js
export default function App() {
return (
<div>
<h1>Hello StackBlitz!</h1>
<p>Start editing to see some magic happen :)</p>
<Inputs />
<Screen />
</div>
);
}
You have to lift the state up to the app.js.
export default function App() {
const [val, setVal] = useState('');
return (
<div>
<h1>Hello StackBlitz!</h1>
<p>Start editing to see some magic happen :)</p>
<Inputs val={val} setVal={setVal} />
<Screen val={val}/>
</div>
);
}
Your inputs.js
export default const Inputs({val, setVal}) => {
const handleChange => (event) {
this.setState({value: event.target.value});
};
const handleSubmit => (event) {
alert('Value: ' + this.state.value);
event.preventDefault();
};
return (
<form onSubmit={handleSubmit}>
<input type="text" value={val} onChange={handleChange} />
<input type="submit" value="Enter" />
</form>
);
}
}
export default Inputs;
Your screen.js
export default const Screen({val}) => {
return (
<div className="screen">
<h1>{val}</h1>
</div>
);
}
```
write your app.js code as
export default function App() {
const [input,setInput] = useState('')
const setInputValue = (value) => {
setInput(value)
}
return (
{Hello StackBlitz!${input}}
Start editing to see some magic happen :)
);
}
and inside your handleChange function write props.setInputValue(event.target.value)
and use input props in Screen.js file as props.input

How to transform inheritance into composition in React (example)?

I have two forms: <Login /> and <Register />. Both have username and password and the register form also has a name field. Also there is a login button and a register button. The common code they share though is just the username and password so I want to refactor my code to have a component <UsernamePassord /> and use it in both <Login /> and <Register />.
What I have done so far (pseudocode):
class UsernamePassword extends React {
constructor() {
this.state = {username: "", password: ""}
}
render() {
return <div>
<input username onChange => setState(username: e.value)
<input password onChange => setState(password: e.value)
</div>
}
class Login extends UsernamePassword {
render() {
return <>
{ super.render() }
<button onClick => this.state.username && this.state.password && signIn() />
}
class Register extends UsernamePassword {
constructor() {
this.state = {
...this.state,
name: ""
}
}
render() {
return <>
<input name onChange => setState(name: e.value)
{ super.render() }
<button onClick => this.state.username && this.state.password && this.state.name && signUp() />
}
I don't like this code at all. It seems really difficult to scale. How can this be done cleaner using composition ?
There are a number of ways to handle this. You could create a component that accepts props (in this case, username and password) and handles the manipulation of values. It subsequently fires an onChange event of some sort that notifies the parent of the change and the parent can manage the state. Alternatively, you could manage the state in the component and just create an event handler prop for alerting parent components of the state. I made a working example of the second scenario based off of your code (changing class-based components for functional ones for simplicity):
import React, { useState } from "react";
import "./styles.css";
const UsernamePassword = ({ onChange }) => {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const handleChange = () => onChange({ username, password });
return (
<div>
<input value={username} onChange={(e) => setUsername(e.target.value)} />
<input value={password} onChange={(e) => setPassword(e.target.value)} />
<button onClick={handleChange}>Click me!</button>
</div>
);
};
const Login = () => {
const onChange = (value) => console.log("Login", value);
return (
<>
<h2>Login</h2>
<UsernamePassword onChange={onChange} />
</>
);
};
const Register = () => {
const onChange = (value) => console.log("Register", value);
return (
<>
<h2>Register</h2>
<UsernamePassword onChange={onChange} />
</>
);
};
export default function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<Register />
<Login />
</div>
);
}

React setState doesn't update the state after submitting input form

I am new in React and want to develop easy app - there is input field from which I want to take values and render list. After added option in text field I want to update this list whith new option.
setState function does not work and I don't know how to connect input submit and list rendering. My code is below.
WaterApp.js
import React from 'react';
import AddWater from './AddWater';
import WaterElements from './WaterElements';
export default class WaterApp extends React.Component {
state = {
quantities: ['aaaaa', 'bbbbb', 'ccccc']
};
handleAddQuantity = (quantity) => {
this.setState(() => ({
quantities: ['ddddd', 'eeeee']
}));
console.log('works');
}
render() {
return (
<div>
<WaterElements quantities={this.state.quantities} />
<AddWater handleAddQuantity={this.handleAddQuantity} />
</div>
)
}
}
AddWater.js
import React from 'react';
export default class AddWater extends React.Component {
handleAddQuantity = (e) => {
e.preventDefault();
const quantity = e.target.elements.quantity.value;
console.log(quantity);
};
render() {
return (
<form onSubmit={this.handleAddQuantity}>
<input type="text" name="quantity" />
<input type="submit" value="Submit" />
</form>
)
}
}
WaterElements.js
import React from 'react';
const WaterElements = (props) => (
<div>
<p>Water Quantity:</p>
{
props.quantities.map((quantity) =>
<p key={quantity}>{quantity}</p>
)
}
</div>
);
export default WaterElements;
I expect list to be ddddd, eeeee at this moment.
You're never calling props.handleAddQuantity
export default class AddWater extends React.Component {
handleAddQuantity = (e) => {
e.preventDefault();
const quantity = e.target.elements.quantity.value;
props.handleAddQuantity(quantity)
};
render() {
return (
<form onSubmit={this.handleAddQuantity}>
<input type="text" name="quantity" />
<input type="submit" value="Submit" />
</form>
)
}
this.setState(() => ({
quantities: ['ddddd', 'eeeee']
}));
should be
this.setState({
quantities: ['ddddd', 'eeeee']
});
and after for add
this.setState({
quantities: [...state.quantities, quantity]
});
to update use this format
this.state({key:value});
not this.state(()=>{key:value});
handleAddQuantity = (quantity) => {
this.setState({
quantities: ['ddddd', 'eeeee']
}));
console.log('works');
}

Why my onInput doesn't work to change props.name?

I am learning React.js and I want to use onInput event to change the name, but it doesn't work.
Why is this happening? Do I write the wrong function(OnInputChange)?
Here is my app.js
import React, { Component } from "react";
import UserInput from "./Components/UserInput";
import UserOutput from "./Components/UserOutput";
class App extends Component {
state = {
Username: [{ name: "Jacky" }]
};
OnInputChange = event => {
this.setState({
Username: [{ name: "event.target.value" }]
});
};
render() {
return (
<div>
<UserInput OnInput={this.OnInputChange} />
<UserOutput name={this.state.Username[0].name} />
</div>
);
}
}
export default App;
my UserInput.js:
import React from "react";
const UserInput = () => {
return (
<div>
<input type="text" />
</div>
);
};
export default UserInput;
my UserOutput.js:
import React from "react";
const UserOutput = props => {
return (
<div>
<p>I am {props.name}</p>
<p>I am {props.name}</p>
</div>
);
};
export default UserOutput;
Changes:
1- You are not assigning onChange handler to input element in UserInput component, only passing that handler in props, automatically it will not work.
2- You are updating the value in state in wrong way, it should be name: event.target.value (not string).
Code:
const UserInput = (props) => {
return(
<div>
<input type="text" onChange={props.OnInput}></input>
</div>
);
}
OnInputChange = (event) => {
this.setState({
Username:[
{ name: event.target.value },
],
});
}
Working Code:
class App extends React.Component {
state = {
Username: [{ name: "Jacky" }]
};
OnInputChange = event => {
this.setState({
Username: [{ name: event.target.value }]
});
};
render() {
return (
<div>
<UserInput OnInput={this.OnInputChange} />
<UserOutput name={this.state.Username[0].name} />
</div>
);
}
}
const UserInput = (props) => {
return (
<div>
<input type="text" onChange={props.OnInput} />
</div>
);
};
const UserOutput = props => {
return (
<div>
<p>I am {props.name}</p>
<p>I am {props.name}</p>
</div>
);
};
ReactDOM.render(<App />, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='app' />
Your OnInput property is not passed down to your input component. It would have to be:
const UserInput = props => {
return(
<div>
<input type="text" onChange={props.OnInput} />
</div>
);
};
Your handler uses a literal string 'event.target.value', it must read the value:
Username: [{ name: event.target.value }],
Also, there is no need to wrap username in an array and another object, you can just use:
Username: event.target.value,
and access this.state.Username.
and initialize as
state = {
Username: "Jacky"
};
1.) You need to pass the event handler to your UserInput component.
const UserInput = ({ onChange }) => {...}
and then
<UserInput onChange={this.OnInputChange} />
2.) You need to use the passed event handler in your input onChange.
<input onChange={onChange} />
3.) You need to use event.target.value not 'event.target.value'.

How to log data from input onto the console in React

I would like to know how to have it where when I press enter on my keyboard, it logs whatever is in the input onto the console. Please help. Thanks!
import React, { Component } from 'react';
import './App.css';
class App extends Component {
onClick() {
alert("CLICKED");
}
onChange(eve) {
console.log(eve.target.value);
}
onSubmit() {
alert("SUBMITTED");
}
render() {
const list = ["Lebron", "Kobe", "Steph", "Kevin"];
return (
<div className="App">
<h1>{
list.map(listitem =>{
return (
<div onClick={this.onClick}>
{listitem}
</div>
)})
}</h1>
<form onSubmit={this.onSubmit}>
<input onChange={this.onChange} />
</form>
</div>
);
}}
export default App;
Please help!
Store the input value in a state variable onChange and then log it to the console onSubmit.
class App extends Component {
constructor(props) {
super(props);
this.state = {
value: ''
};
}
onChange = event => {
this.setState({ value: event.target.value});
}
onSubmit = event => {
const { value } = this.state;
event.preventDefault();
console.log(value);
}
render() {
const list = ["Lebron", "Kobe", "Steph", "Kevin"];
const { value } = this.state;
return (
<div className="App">
...
<form onSubmit={this.onSubmit}>
<input onChange={this.onChange} value={value}/>
</form>
</div>
);
}
}

Resources