reactjs - 用新数据重新加载子组件
问题描述
在从 NuevoTurnoPage.js(父级)中选择它后,我试图用新值更新我的 ListaTurnos.js(子级),但是在设置状态变量之后,它不会更新子组件。显然我做错了什么,但我无法弄清楚。孩子只渲染第一次。
这是 NuevoTurnoPage.js,父组件。
export default function NuevoTurnoPage(props) {
const classes = useStyles();
const { ...rest } = props;
const isLoggedIn = React.useState(localStorage.getItem("user") ? true : false);
const [cardAnimaton, setCardAnimation] = React.useState("cardHidden");
const [esp, setEsp] = React.useState('');
const [profesional, setProfesional] = React.useState('');
const [dniMedico, setDniMedico] = React.useState(-1);
const [turnoElegido, setTurnoElegido] = React.useState('');
const [dni, setDNI] = React.useState('');
const [estado, setEstado] = React.useState(false);
const [arrayMedicos, setArrayMedicos] = React.useState([]);
const handleEspChange = (event) => {
setEsp(event.target.value);
};
const handleProfChange = (event) => {
setProfesional(event.target.value);
setDniMedico(event.target.value);
console.log("se actualizo el profesional", dniMedico);
}
const handleSelectTurno = (event) => {
setTurnoElegido(event.target.value);
}
const handleDNIChange = (event) => {
console.log(event.target.value);
setDNI(event.target.value);
}
const solicitarTurno=()=> {
if (turnoElegido!=="" && dni!=="" && profesional!=="" && esp!=="") {
validarSelectTurno();
}
else {
alert("Debe completar todos los campos");
}
}
useEffect(()=>{
async function componentDidMount() {
let data = await getMedicos();
console.log(data);
for(let i=0; i<data.data.length; i++) {
arrayMedicos.push(data.data[i]);
}
console.log(arrayMedicos)
setArrayMedicos(arrayMedicos);
console.log("Array seteada")
}
componentDidMount();
},[]);
//Ejecuto el endopoint para validar login
const validarSelectTurno= async function() {
let datos = {
dni: dni,
razon: esp,
fecha: turnoElegido.fecha,
dniMedico: turnoElegido.dniMedico,
estado: "Asignado"
}
let getAsignacionTurno = await asignarTurno(datos);
if (getAsignacionTurno.rdo===0 ) {
setEstado(true);
} else {
alert(getAsignacionTurno.mensaje)
}
}
const redirect= ()=>{
if (estado) {
return <Redirect to='/profile' />
}
}
setTimeout(function () {
setCardAnimation("");
}, 700);
if (isLoggedIn[0] == false) {
return (
<div>
<Header
absolute
color="transparent"
brand="Home"
rightLinks={<HeaderLinks />}
{...rest}
/>
<div
className={classes.pageHeader}
style={{
backgroundImage: "url(" + image + ")",
backgroundSize: "cover",
backgroundPosition: "top center"
}}
>
<div className={classes.container}>
<GridContainer justify="center">
<GridItem xs={12} sm={12} md={4}>
<Card className={classes[cardAnimaton]}>
<form className={classes.form}>
<h3 className={classes.divider}>No tienes permiso para ver esta pagina</h3>
<CardBody>
</CardBody>
</form>
</Card>
</GridItem>
</GridContainer>
</div>
<Footer whiteFont />
</div>
</div>
);
} else {
return (
<div>
<Header
absolute
color="transparent"
brand="Home"
rightLinks={<HeaderLinks />}
{...rest}
/>
{redirect()}
<div
className={classes.pageHeader}
style={{
backgroundImage: "url(" + image + ")",
backgroundSize: "cover",
backgroundPosition: "top center"
}}
>
<div className={classes.container}>
<GridContainer justify="center">
<GridItem xs={12} sm={12} md={4}>
<Card className={classes[cardAnimaton]}>
<form className={classes.form}>
<h3 className={classes.divider}>Seleccion de turno</h3>
<CardBody>
<FormControl className={classes.formControl}>
<InputLabel id="demo-simple-select-helper-label">Elija especialidad</InputLabel>
<Select
labelId="demo-simple-select-helper-label"
id="demo-simple-select-helper"
value={esp}
onChange={handleEspChange}
>
<MenuItem value="">
<em>Debe seleccionar una opcion</em>
</MenuItem>
<MenuItem value={10}>Consulta general</MenuItem>
<MenuItem value={20}>Pediatria</MenuItem>
<MenuItem value={30}>Ortodoncia</MenuItem>
<MenuItem value={40}>Cardiologia</MenuItem>
<MenuItem value={50}>Análisis de sangre</MenuItem>
<MenuItem value={60}>Rayos</MenuItem>
<MenuItem value={70}>Electrocardiograma</MenuItem>
<MenuItem value={80}>Tomografia computada</MenuItem>
</Select>
<FormHelperText>Estamos trabajando para agregar mas especialidades</FormHelperText>
</FormControl>
<FormControl className={classes.formControl}>
<InputLabel id="demo-simple-select-helper-label">Elija el profesional</InputLabel>
<Select
labelId="demo-simple-select-helper-label"
id="demo-simple-select-helper"
value={profesional}
onChange={handleProfChange}
>
<MenuItem value={-1}>
<em>Debe seleccionar una opcion</em>
</MenuItem>
{arrayMedicos.map(medico=> (
<MenuItem key={medico.dni} value={medico.dni}>{medico.name +" " + medico.surname}</MenuItem>
))}
</Select>
<FormHelperText>Estamos trabajando para agregar mas profesionales</FormHelperText>
</FormControl>
<FormControl>
<ListaTurnos dni={dniMedico} ></ListaTurnos>
</FormControl>
<CustomInput
labelText="DNI"
id="name"
formControlProps={{
fullWidth: true
}}
inputProps={{
type: "number",
onChange: (event) => handleDNIChange(event),
endAdornment: (
<InputAdornment position="end">
<FingerprintIcon className={classes.inputIconsColor} />
</InputAdornment>
)
}}
/>
</CardBody>
<CardFooter className={classes.cardFooter}>
<Button onClick={solicitarTurno} simple color="primary" size="lg">
Asignar Turno
</Button>
</CardFooter>
</form>
</Card>
</GridItem>
</GridContainer>
</div>
<Footer whiteFont />
</div>
</div>
);
}
}
这是子组件 ListaTurnos.js
const useStyles = makeStyles((theme) => ({
root: {
width: '100%',
height: 400,
maxWidth: 300,
backgroundColor: theme.palette.background.paper,
},
}));
var arrayTurnos = [];
function renderRow(props) {
const { index, style } = props;
return (
<ListItem button style={style} key={index}>
<ListItemText primary={parseDate(arrayTurnos[index].fecha)} />
</ListItem>
);
}
function parseDate(date) {
let dia = new Date(date);
let value = "Dia: " + dia.getDate() + "/" + dia.getMonth() + "/" + dia.getFullYear() + " Horario:" + dia.getHours() + ":" + dia.getMinutes()
return value
}
renderRow.propTypes = {
index: PropTypes.number.isRequired,
style: PropTypes.object.isRequired,
};
export default function VirtualizedList(props) {
const classes = useStyles();
const [array, setArray] = React.useState([]);
const [dniMedico, setDniMedico] = React.useState(props.dni);
useEffect(()=>{
async function componentDidUpdate() {
console.log("este es el valor de el dni del medico en el componente lista", dniMedico);
if (dniMedico != -1 && dniMedico != undefined) {
let data = await getTurnosDisponibles(dniMedico);
console.log(data);
for(let i=0; i<data.data.length; i++) {
arrayTurnos.push(data.data[i]);
}
setArray(arrayTurnos);
console.log(arrayTurnos.length);
}
}
componentDidUpdate();
},[]);
return (
<div className={classes.root}>
<FixedSizeList height={400} width={300} itemSize={46} itemCount={arrayTurnos.length}>
{renderRow}
</FixedSizeList>
</div>
);
}
如果您需要所有代码,这里是 github 存储库的链接:https ://github.com/huguenn/IA-Grupo7
解决方案
您的问题是您正在复制孩子的状态:
const [dniMedico, setDniMedico] = React.useState(props.dni);
从道具创建状态是不好的做法。这个 state 只需要第一个 props 来初始化它自己的 state,并且dniMedico
只会在你调用setDniMedico
Child 时更新。发生在父状态的更新与子状态的更新无关。dni
你应该只使用你从父母那里得到的道具:
export default function VirtualizedList(props) {
const classes = useStyles();
const [array, setArray] = React.useState([]);
const dniMedico = props.dni; // though it makes more sense to pass props as dniMedico instead of dni
如果最终您需要更新子节点dniMedico
的父状态,那么您也可以作为 prop 传递下去SetDniMedico
。
推荐阅读
- javascript - 如何阻止我的递归除法迷宫算法堵塞漏洞?
- python - 如何最好地使用坐标列表从二维 numpy 数组中选择值?
- javascript - ReactJS(带有coreui):下拉组件没有反映正确的菜单点击
- google-chrome - 更改 (Chrome) Lighthouse 报告的最终屏幕截图分辨率
- azure - 无法在 Azure 中获取我的公共 IP 的资源 ID
- webpack - babel polyfill 与 webpack 中断
- odata - 如何对 Azure 逻辑应用“获取文件”操作中的路径进行 OData 查询筛选?
- javascript - 如何在 discord.js 中做出随机响应?
- python - 如何在 discord.py 中使用权限?
- arrays - 在 Swift 中,我如何将一个句子数组拆分为多个数组,并由指定的开头和结尾句子分隔?