reactjs React -组件在删除请求后未重新呈现

fzwojiic  于 2022-12-29  发布在  React
关注(0)|答案(4)|浏览(199)

我有一个问题,从我的列表中删除元素后,组件不想重新呈现。当我通过路由到一些子页面,然后回来,项目已经被删除,同样如果我排序列表,然后它也消失了。问题是,我不想强迫用户刷新网站或排序,以查看效果。它曾经工作,如果我传递到
deviceList props as a "props.data" instead of "devices"
(will粗体代码中的地方)。有人知道如何修复它吗?我仍然是一个新的React挂钩,也许我只是需要调整useEffect更好一点, prop 。selectedDevices是从redux和只是得到删除的项目的ID,我的代码:
母公司:

function App(props) {
  const [data, setData] = useState("")
  const [filter, setFilter] = useState([])

  useEffect(() => getDeviceDataTotal(), [])

  const getDeviceDataTotal = () => {
    console.log('refresh clicked')
    fetch("http://localhost:4000/device")
      .then(res => res.json())
      .then(res => setData(res))
      .catch(err => {
        throw err;
      });
  };

  const deleteDevices = (e) => {
    console.log('delete clicked')
    props.selectedDevices.map(el => {
      return fetch(`http://localhost:4000/device/delete/${el}`, {
        method: "DELETE"
      })
        .then(res => res.json())
        .then(() => getDeviceDataTotal())
        .catch(err => {
          throw err;
        });
    });
  }

  const filterList = e => {
    let filteredList;
    filteredList = data.filter(el => {
      return el.device_id.includes(searched);
    });
    setFilter(filteredList)
  };

  return (
    <BrowserRouter>
      <MuiThemeProvider theme={createMuiTheme(theme("#96BF1B", "#ffffff"))}>

        <Switch>
          <Route
            exact
            path="/"
            render={() => <Dashboard classes={classes} dataDevice={data} refresh={getDeviceDataTotal} filtered={filter} filterList={filterList} deleteDevices={deleteDevices}/> }
          />
          ......
        </Switch>
      </MuiThemeProvider>
    </BrowserRouter>
  );
}

子组件:

function Dashboard(props) {
  const [selectedSort, setSelectedSort] = useState("1")
  const [devices, setDevices] = useState(props.dataDevice)

  useEffect(() => {
    let isSubscribed = true
    const fetchData = async() => {
      try {
        const res = await fetch("http://localhost:4000/device")
        const response = await res.json()
        if (isSubscribed) {
          setDevices(response)
         }
      } catch (err) {
        console.log(err)
      }
    }

    fetchData()
    return () => isSubscribed = false
  },[])

  useEffect(() => props.refresh() ,[devices])

  useEffect(() => sortDeviceData(), [selectedSort])

  const sortDeviceData = () => {
    switch(selectedSort) {
      case "device":
        (filtered.length ? filtered : dataDevice).sort(function(a,b) {
          return (a.device_id.toUpperCase() < b.device_id.toUpperCase()) ? -1 : (a.device_id.toUpperCase() > b.device_id.toUpperCase()) ? 1 : 0
        })
        setDevices(dataDevice)
        break;
      case "customer":
        (filtered.length ? filtered : dataDevice).sort(function(a,b) {
          return (a.customer.toUpperCase() < b.customer.toUpperCase()) ? -1 : (a.customer.toUpperCase() > b.customer.toUpperCase()) ? 1 : 0
        })
        setDevices(dataDevice)
        break;
      case "server":
        (filtered.length ? filtered : dataDevice).sort(function(a,b) {
          return (a.server.toUpperCase() < b.server.toUpperCase()) ? -1 : (a.server.toUpperCase() > b.server.toUpperCase()) ? 1 : 0
        })
        setDevices(dataDevice)
        break;
      case "creation":
        (filtered.length ? filtered : dataDevice).sort(function(a,b) {
          return (a.createdAt.toUpperCase() < b.createdAt.toUpperCase()) ? -1 : (a.createdAt.toUpperCase() > b.createdAt.toUpperCase()) ? 1 : 0
        })
        setDevices(dataDevice)
        break;
      case "update":
        (filtered.length ? filtered : dataDevice).sort(function(a,b) {
          return (a.updatedAt.toUpperCase() < b.updatedAt.toUpperCase()) ? -1 : (a.updatedAt.toUpperCase() > b.updatedAt.toUpperCase()) ? 1 : 0
        })
        setDevices(dataDevice)
        break;    
      default: 
        return setDevices(dataDevice)
    }
  }

  const { classes, logged, dataDevice, filtered } = props;
  return logged ? (
    <main style={{ display: "flex" }} key={dataDevice}>
      <section className={classes.sectionLeftContainer}>

        <div className={classNames(classes.search, classes.tableBackground)}>
          <InputBase
            placeholder="Search…"
            classes={{
              root: classes.inputRoot,
              input: classes.inputInput
            }}
            inputProps={{ "aria-label": "Search" }}
            onChange={e => props.getSearched(e.target.value)}
          />
          <Button
            variant="outlined"
            className={classes.searchBtn}
            onClick={e => props.filterList(e)}
          >
            Search
          </Button>
          <Button
            variant="outlined"
            className={classes.btnAddDevice}
            onClick={e => {
              if (window.confirm("Are you sure you want to delete this device")) {
                props.deleteDevices(e);
              }
            }}
          >
            <DeleteIcon />
            Delete devices
          </Button>
        </div>
        <div>
          <FormControl className={classes.selectContainer}>

            <Select 
              value={selectedSort} 
              style={{position: 'absolute', right: 0, bottom: 10, width: 150}}
              onChange={e => setSelectedSort(e.target.value)}
              >
              <MenuItem value="1">Default</MenuItem>
              <MenuItem value="device">Device</MenuItem>
              <MenuItem value="customer">User</MenuItem>
              <MenuItem value="server">Server</MenuItem>
              <MenuItem value="creation">Creation date</MenuItem>
              <MenuItem value="update">Update date</MenuItem>
            </Select>
          </FormControl>
        </div>
        <div>
          <DeviceList
            classes={classes}
            **deviceData={devices} if props.data - works well but sorting doesn't work**
            filtered={filtered}
          />
        </div>
      </section>
    </main>
}
mmvthczy

mmvthczy1#

强制React组件呈现有多种方法,但本质上是相同的。第一种方法是使用this.forceUpdate(),它跳过了shouldComponentUpdate

someMethod() {
    // Force a render without state change...
    this.forceUpdate();
}

假设您的组件具有状态,则还可以调用以下内容:

someMethod() {
    // Force a render with a simulated state change
    this.setState({ state: this.state });
}

可能有一种更好、更“React-y”的方式来正确地呈现组件,但如果您迫切希望根据命令来呈现组件,这将是可行的。

c0vxltue

c0vxltue2#

你应该把这个删除函数向上拉到保存设备列表的父组件,然后把这个函数作为 prop 向下传递,从包含你想要删除的设备的子组件调用它。

const deleteDevices = (e) => {
  return fetch(`http://localhost:4000/device/delete/${e}`, {
    method: "DELETE"
  })
  .then(res => res.json())
  .then(_ => setDevice(devices.filter(device => device !== e)))
  .catch(err => {
    throw err;
  });
}
brgchamk

brgchamk3#

将获取逻辑分离到一个函数中,并在删除请求后调用它,以便更新数据。

const getData = () => {
  // fetch data
}

useEffect(() => {
  getData()
}, [])

const deleteData = () => {
  fetch(...).then(() => {
    getData()
  })
}
e5nszbig

e5nszbig4#

尝试更新您的父组件useEffect钩子。

//...

const getDeviceDataTotal = () => { 
    // Api call...
};

// Reference the getDeviceDataTotal function inside the hook.
useEffect(getDeviceDataTotal, []);

//...

或者将API调用函数 Package 在useCallback钩子中,并将其作为依赖项包含在useEffect钩子中。

//...

const getDeviceDataTotal = useCallback(() => { 
    // Api call...
},[]);

// Include getDeviceDataTotal as a dependency.
useEffect(() => getDeviceDataTotal(), [getDeviceDataTotal]);

//...

相关问题