Ad
React: SetState Does Not Update Visual Component
A function component does not perform its visual update when the state changes.
I provide a minimal example of my component where I set a new state but the component does not update in the browser.
import * as React from "react"
import { Button, makeStyles, Grid, TextField, createStyles } from '@material-ui/core'
import ReactDOM from "react-dom";
const styles = makeStyles(theme => createStyles({
container: {
display: 'flex',
flexWrap: 'wrap',
},
textField: {
marginLeft: theme.spacing(1),
marginRight: theme.spacing(1),
},
button: {
margin: theme.spacing(1),
}
}))
export interface RTestData {
title: string
}
interface Props {
data: RTestData[]
}
const testData: RTestData[] = [{title: "AA"}, {title: "BB"}, {title: "CC"}, {title: "DD"}, {title: "EE"}]
export const RTestContainer: React.FunctionComponent<Props> = (props) => {
const [count, setCount] = React.useState(0)
const [data, setData] = React.useState(props.data[count])
const classes = styles()
const handleClick = () => (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
console.log(`BUTTON click`)
const target = e.target
setCount(count + 1)
setData(props.data[count])
console.log("data " + JSON.stringify(props.data) + " ->" + JSON.stringify(data))
}
return (
<Grid container spacing={2}>
<Grid item xs={12}>
<RTestForm title={data.title}/>
</Grid>
<Grid item>
<Button
variant="contained"
color="primary"
className={classes.button}
onClick={handleClick()}
>
Next!!
</Button>
</Grid>
</Grid>
)
}
export const RTestForm: React.FunctionComponent<RTestData> = (props) => {
const [title, setTitle] = React.useState(props.title)
const handleChange = () => (e: React.ChangeEvent<HTMLInputElement>) => {
const target = e.target
const value = target.value
console.log("Title change ->" + title)
setTitle(value)
}
const classes = styles()
return (
<form className={classes.container} noValidate autoComplete="off">
<Grid container spacing={2}>
<Grid item xs={12} sm={6} lg={6}>
<TextField
required
label="Title"
value={title}
onChange={handleChange()}
className={classes.textField}
margin="normal"
variant="filled"
/>
</Grid>
</Grid>
</form>
)
}
ReactDOM.render(<div id="root">
<RTestContainer data={testData}/>
</div>, document.getElementById('root'));
A click on the button should select and display the next data item, e. g. the textfield displays "AA", "BB" and so on.
Ad
Answer
On handleClick
you change RTestContainer
state but it doesn't affect RTestForm
state.
// v On handleClick changes `data` state
<RTestForm title={data.title} />
// Changing props won't re-initial the state. v
const [title, setTitle] = React.useState(props.title);
Try adding a listener for props.title
change with useEffect
:
export const RTestForm: React.FunctionComponent<RTestData> = props => {
const [title, setTitle] = React.useState(props.title);
React.useEffect(() => {
setTitle(props.title);
}, [props.title]);
return <>...</>
};
Ad
source: stackoverflow.com
Related Questions
- → Import statement and Babel
- → should I choose reactjs+f7 or f7+vue.js?
- → Uncaught TypeError: Cannot read property '__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
- → .tsx webpack compile fails: Unexpected token <
- → React-router: Passing props to children
- → ListView.DataSource looping data for React Native
- → React Native with visual studio 2015 IDE
- → Can't test submit handler in React component
- → React + Flux - How to avoid global variable
- → Webpack, React & Babel, not rendering DOM
- → How do I determine if a new ReactJS session and/or Browser session has started?
- → Alt @decorators in React-Native
- → How to dynamically add class to parent div of focused input field?
Ad