Any way to render a dynamically added modal from api with routing in react?

倾然丶 夕夏残阳落幕 提交于 2019-12-11 15:49:56

问题


working on a project for a hospital in which data on patients gets pulled from their api and gets loaded as cards on the page (will provide screenshots). When you click on a card more info of the patient gets pulled up as a modal. The goal here is for them to render when someone searches for it based on slug. Each endpoint from the api has a slug: API Data

for example if you go to localhost:3000/WebersWarriors (localhost:3000/${shirt.slug}) it will render that specific modal and if you click on a card it would append "WebersWarriors" to the end of the URL. Any help or suggestions would be greatly appreciated thank you! Layout

When card gets clicked

Modal code being displayed dynamically:



    const TshirtItem = props => {
      const classes = useStyles();
      const { shirt } = props;
      const theme = useTheme();
      const [open, setOpen] = React.useState(false);
      const matches = useMediaQuery(theme.breakpoints.down('sm'));

      const handleClickOpen = () => {
        setOpen(true);

        setTimeout(() => {
          handleClose();
        }, 30000);
      };

      const handleClose = () => {
        setOpen(false);
      };

      const handleDetail = content => (
        <Dialog
          fullScreen={matches}
          className={classes.dialog}
          open={open}
          TransitionComponent={Transition}
          keepMounted
          onClose={handleClose}
          aria-labelledby="alert-dialog-slide-title"
          aria-describedby="alert-dialog-slide-description"
        >
          <DialogContent>
            <Grid container>
              <Grid item>
                {shirt.ar_lens_card !== null ? (
                  <img
                    key={shirt.ar_lens_card.id}
                    src={shirt.ar_lens_card.url}
                    title={shirt.ar_lens_card.name}
                    alt={shirt.ar_lens_card.name}
                    className={classes.dialog_img}
                  />
                ) : null}
              </Grid>

              <Grid item container>
                <Grid item xs={2} container direction="column">
                  <Typography
                    className={classes.tshirt_number}
                    color="textSecondary"
                  >
                    #{shirt.Tshirt_Number}
                  </Typography>
                </Grid>
                <Grid item xs={10} container>
                  <Grid item xs>
                    <Typography className={classes.label}>Team</Typography>
                    <Typography className={classes.team_name}>
                      {shirt.team_name}
                    </Typography>

                    <hr className={classes.hr} />

                    <Typography className={classes.patient_name}>
                      {shirt.patient_first_name}
                    </Typography>
                    <Typography
                      color="textSecondary"
                      className={classes.patient_diagnosis}
                    >
                      {shirt.patient_diagnosis}
                    </Typography>
                    <Typography className={classes.patient_bio}>
                      {shirt.patient_bio}
                    </Typography>
                  </Grid>
                </Grid>
                {matches ? (
                  <IconButton
                    edge="start"
                    color="inherit"
                    onClick={handleClose}
                    aria-label="close"
                    className={classes.arrowback_icon}
                  >
                    <ArrowBackIosIcon fontSize="large" />
                  </IconButton>
                ) : null}
              </Grid>
            </Grid>
          </DialogContent>
        </Dialog>
      );


回答1:


Your code will be pretty similar to the React-router gallery example.

You just need to fetch your data in your list component and render the cards. In the demo below I've used Bulma for styling and React-masonry-css for creating the Masonry grid.

The demo can be found here.

The important part of the demo is the Cards component with the following code:

const Cards = () => {
  const [users, setUsers] = useState([]);
  const [isFetching, setFetchStatus] = useState(true);

  useEffect(() => {
    const fetchUsers = async () => {
      try {
        const { data } = await axios.get(API_URL);
        setUsers(data);
      } catch (err) {
        console.error("failed", err);
      }

      setFetchStatus(false);
    };

    fetchUsers();
  }, []);

  const location = useLocation();
  const background = location.state && location.state.background;

  return isFetching ? (
    "loading..."
  ) : (
    <Fragment>
      <Switch location={background || location}>
        <Route path="/" component={() => <Home users={users} />} />
      </Switch>

      {background && (
        <Route
          path="/user/:id"
          component={() => <RouterModal users={users} />}
        />
      )}
    </Fragment>
  );
};

It is like in the gallery example except the useEffect that fetches the data from https://jsonplaceholder.typicode.com/ API.

useEffect hook with an empty array as a parameter is in a class-based component the life cycle method componentDidMount - so it's just called on the first render.

Things you could improve in your final app:

  • Check caching of the fetched data
  • Limit the rendered cards (e.g. show only 1000 cards and filter by letters)
  • Add a search field with typeahead
  • Change the query to slug (in the demo it's the id because there's no slug in the fake api data)
  • Move the components into different files (kept everything in one file just for the demo)


来源:https://stackoverflow.com/questions/58960817/any-way-to-render-a-dynamically-added-modal-from-api-with-routing-in-react

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!