首页 > 解决方案 > 用新数据重新加载子组件

问题描述

在从 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

标签: reactjs

解决方案


您的问题是您正在复制孩子的状态:

const [dniMedico, setDniMedico] = React.useState(props.dni);

从道具创建状态是不好的做法。这个 state 只需要第一个 props 来初始化它自己的 state,并且dniMedico只会在你调用setDniMedicoChild 时更新。发生在父状态的更新与子状态的更新无关。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


推荐阅读