React is a popular library for creating web apps and mobile apps.
In this article, we’ll look at some tips for writing better React apps.
Programmatically Update Query Params in React Router
We can update query parameters with React Router by calling history.push
.
We can either call it with an object:
history.push({
pathname: '/cars',
search: '?color=green'
})
or:
history.push('/car?color=green')
Change Event for contentEditable
Instead of listening to the change event to listen for content changes in a contentEditable
element, we listen to the input event.
For instance, we can write:
<div
contentEditable
onInput={e => console.log(e.currentTarget.textContent)}
>
foo bar
</div>
We pass an event handler to the onInput
prop.
Then we can get the value of the content with e.currentTarget.textContent
.
ReactJS Lifecycle Method Inside a Function Component
We replace the lifecycle methods with hooks in a function component.
useEffect
is equivalent to the lifecycle hooks.
And useState
is equivalent to setState
.
For instance, we can write:
const Grid = (props) => {
const [data, setData] = useState();
const getData = () => {
const data = await fetchData();
setData(data);
}
useEffect(() => {
getData();
}, []);
return(
<div>
{data.map(d => <Row data={data} />)}
</div>
)
}
We have the useState
hook which returns the array with the latest state value and function to set the state.
Then we have the useEffect
hook, which lets us commit side effects.
The 2nd argument is the values to watch for.
If it’s empty, then the callback in useEffect
only runs when the component is mounted.
We can have multiple useEffect
hooks in one component, unlike the lifecycle methods for class components.
Then we render the items in the JSX expression we return.
The equivalent of componentWillUnmount
is the function that we return in the useEffect
callback.
For instance, we can write:
useEffect(() => {
window.addEventListener('click', handler);
return () => {
window.removeEventListener('click', handler);
}
}, [])
We call any code that clears up resources in the function we return in the useEffect
callback.
The equivalent of componentDidUpdate
is passing in values to the array in the 2nd argument of useEffect
.
For instance, if we want to watch for the change in values of the foo
state and bar
prop, we can write:
useEffect(() => {
//...
}, [foo, props.bar])
We just pass them into the array and then we always get the latest value.
Can’t Type into React Input Text Field
If we want to be able to type into an input text field, then we’ve to make it a controlled input.
This means we set a state’s value with the latest entered value in an event handler.
And we pass that into the onChange
prop.
And we set the value
prop to the value of that state.
For instance, we write:
<input
type="text"
value={this.props.value}
onChange={this.handleChange}
/>
to do that.
For a full example, we can write:
class Form 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(this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
The handleChange
method sets the latest value that’s entered, which is stored in event.target.value
as the value of the value
state.
Then we can get that in the handleSubmit
method when we click on Submit.
Multiple Path Names for the Same Component in React Router
We can assign multiple paths to redirect to the same path by passing in an array with all the path names to the path
prop.
For instance, we can write:
<Router>
<Route path={["/home", "/user", "/profile"]} component={Home} />
</Router>
We just pass them into the Router
component’s path
prop and they’ll all match.
Each pat in the array is a regex string.
Conclusion
Multiple path names can be assigned to go to the same component.
We can use history.push
to update query parameters.
There are equivalents to component lifecycle methods in class components in function components.
To let us type into an input, we’ve to set the state with the latest inputted value and the set that as the value.