Development Tips for React Developers
1. Updating an object with setState in React
> For example
Given the state ,
this.state = {jasper:{name: 'jasper', age:28}}
You can update an object using 2 methods
Object.assign()
- Spread Operator …
1 > Object.assign
this.setState(prevState => {
let jasper = Object.assign({}, prevState.jasper)
jasper.name = 'someothername'
return { jasper }
})
2 > Spread Operator
this.setState(prevState => ({
jasper: { ...prevState.jasper,
name: 'something'
}
}))
2. Updating a nested object in React
Object.assign
& Spread Operator creates only shallow copy
> For example
Given the nested object ,
this.state = {
"food":{
"sandwich":{
"capsicum":true,
"crackers":true,
"mayonnaise":true
},
"pizza":{
"jalapeno":true,
"extraCheese":false
}
}
}
- update extraCheese of Pizza object (using Spread Operator)
> Spread Operator for nested object
this.setState(prevState => (
{
"food":{
"...prevState.food",
"pizza":{
"...prevState.food.pizza",
"extraCheese":true
}
}
})
)
3. Deploy App on a subdirectory
- If you want to deploy App on a Subdirectory such as
https://myapp.com/directory-name
You can deploy app on a subdirectory using 2 methods
- Set the base name
basename
- Set the app
homepage
inpackage.json
1 > Set the base name
<Router basename={'/directory-name'}>
<Route path='/' component {Home} />
...
</Router>
- Setting the
basename
attribute on the<Router />
component tells React Router that the app will be served from a subdirectory
2 > Set the app homepage in package.json
- In
package.json
file, set the propertyhomepage
npm run build
command comes fromcreact-react-app
andnpm run build
usehomepage
property to make sure the production build points to the correct location- By default, CRA (Create React App) produces a build assuming your app is hosted at the server root
- To override this, specify the
homepage
in yourpackge.json
"homepage" : "http://mywebsite.com/relativepath"
4. Render nested object
- Sometimes, you will find the data in nested object type
- Object is NOT so easy to iterate compared to array in JavaScript. So I recommend you to convert the object into an array using
Object.keys()
method
Given the nested object,
const fruits = {
"apple":{
"price":10,
"weight":2.5,
"color":"red"
},
"banana":{
"price":5,
"weight":1.2,
"color":"yellow"
}
}
> Object.keys() and use the key to map
render() {
Object.keys(fruits).map(function(fruit_name){
return(
<tr key={fruit_name}>
<tr>
<td>
<b> Template: {fruit_name} </b>
</td>
</tr>
{fruits[fruit_name].items.map(function(item){
return(
<tr key={item.id}>
<td>{item}</td>
</tr>
)
})}
</tr>
)
})
}
5. Simple nested Mapping
const mscList = classroomSummary.map((classRoom, ind) => (
classRoom.map(classData => (
<MSCItem classData={classData} />
))
))
6. Detect Route Change
- For many times, you will find a needs to detect route change and do something (i.e., change the state “loading” into
false
whenever there is a page refresh or route change) - To detect route change in React, you need to use
listen
method inhistory
property
For example,
- I want to change my state
expanded
tofalse
whenever there is a route change
> listen method in history property
constructor(props){
super(props);
this.props.history.listen((location, action) => {
// console.log('history changed')
this.routeChange();
})
}
// routeChange function
routeChange = () => {
const { BaseActions } = this.props
BaseActions.sideBar({expanded: false})
}
7. history push INSTEAD OF window.location
- The main difference between
history.push
andwindow.location
is that
// CLIENT SIDE
history.push('/')// SERVER SIDE
window.location('/')
- Use history API
history.push('/')
to refresh the page for a better UX
8. Query String
- Query String is often used for passing parameters (data) around both in CLIENT & SERVER side
- Installation —
npm install query-string
- I used Query String to filter data using the selected options
- For example, if a user choose
Europe
, I passEurope
as a queryString...URL...?Region=Europe
and filter the data using the value ofRegion
in URL
> query string
- push the state or props to URL using history.push method
resetBtn = () => {
const { history, schoolid,
selectedAgeValue, selectedDomain } = this.props; history.push(`/reports/disadmin/${schoolid}
?age=${selectedAgeValue}&domain=${selectedDomain}`)
}
- then use it using queryString (e.g.,
queryString.parse
method - In this example, I get the values for key age & domain and update Redux
import queryString from 'query-string'const params = queryString.parse(window.location.search)const param_selectedAgeValue = params.ageconst param_selectedDomain = params.domainreturn state.set('param_selectedAgeValue', param_selectedAgeValue)