为了账号安全,请及时绑定邮箱和手机立即绑定

使用 useEffect() 管理功能组件的状态

使用 useEffect() 管理功能组件的状态

江户川乱折腾 2022-06-16 15:40:24
假设我有一个 App.jsx:应用程序.jsxconst App = () => {    return (        <React.Fragment>            <NavBar />            <BooksList />            <TextEditor />        </React.Fragment>    )}export default App;和是 2BooksList个TextEditor功能组件。在一个组件中,我能够将编辑器的内容保存到数据库中:编辑器.jsxconst TextEditor = () => {    return(        <*editor related stuff*>    )}const SaveContent = ({ value, icon }) => {    return (        <SaveButton            onMouseDown={async () => {                console.log(JSON.stringify(value));                const response = await fetch('/add_book', {                    method: 'POST',                    headers: {                        'Content-Type': 'application/json'                    },                    body: JSON.stringify(value)                })                if (response.ok) {                    console.log('response okay')                }            }}        >            <Icon icon={icon}></Icon>        </SaveButton>    )}这成功写入我的数据库。我想让 BookList 组件在我保存/删除项目时自动更新数据库的内容。这是我目前拥有的 BookList 组件:BooksList.jsxconst BooksList = () => {    const [books, setBooks] = useState([]);    useEffect(() => {        fetch('/get_books')        .then(response =>             response.json()        .then(data => {            setBooks(data)        })        );    }, [])    return (        <*list of saved editors*>    )}所以在加载时,如果数据库是空的,它什么也不显示。当我保存到数据库时,它什么也没显示,然后当我刷新页面时,它显示我想要取回的数据。我希望能够保存数据并自动看到上述组件刷新和更新。我是 React 和 JS 的新手,所以任何指针都会很棒。我认为可能需要重写以使用基于类的组件来更轻松地管理状态?但我不确定。我的基本理解是,这useEffect()是基于类的安装方法的功能等价物。这让我相信这是可以做到的。但是,我读过有状态组件应该使用基于类的组件。
查看完整描述

3 回答

?
哆啦的时光机

TA贡献1779条经验 获得超6个赞

有几种不同的方法可以做到这一点,这完全取决于您的组件的结构。底线是,当您成功 POST 到数据库时,您需要触发您的 GET 请求。一个快速而肮脏的解决方案是将 GET 请求移到一个单独的函数中,并在 useEffect 中调用它,并将函数作为道具传递下去。像这样的东西:


编辑器.jsx


const SaveContent = ({ value, icon, refreshBooksList }) => {

    const addBook = useCallback(async () => {

        const response = await fetch('/add_book', {

            method: 'POST',

            headers: {

                'Content-Type': 'application/json'

            },


            body: JSON.stringify(value)


        })


        if (response.ok) {

            console.log('response okay')

            refreshBooksList()

        }

    }, [value, refreshBooksList])


    return (

        <SaveButton

            onMouseDown={addBook}

        >

            <Icon icon={icon}></Icon>

        </SaveButton>

    )

}

BooksList.jsx


const BooksList = () => {

    const [books, setBooks] = useState([]);


    const getBooksList = useCallback(async () => {

        await fetch('/get_books')

            .then(response => 

                response.json()

            .then(data => {

                setBooks(data)

            })

        );

    }, [setBooks])


    useEffect(() => {

        getBooksList()

    }, [])


    return (

        <*list of saved editors*>

    )

}

如果这两个组件不是父/子,那么您需要将getBooks函数向上移动到共享父级。


根据 API 返回的内容,您可以完全删除额外的 GET 请求并简单地更新状态。如果是这种情况,您可以考虑使用 React Context 来避免传递道具。


查看完整回答
反对 回复 2022-06-16
?
元芳怎么了

TA贡献1798条经验 获得超7个赞

如果 Editor 和 BookList 不在同一个 Parent 组件内,可以使用事件在 Editor 和 BookList 之间进行通信。Editor 可以发送事件,BookList 可以监听这些事件。

书单

document.body.addEventListener('updateBookList', onUpdateBookList, false);

编辑

const myEvent = new CustomEvent('updateBookList');
document.body.dispatchEvent(myEvent);


查看完整回答
反对 回复 2022-06-16
?
郎朗坤

TA贡献1921条经验 获得超9个赞

如果您的 Editor 和 BookList 组件在同一个父组件内,那么您可以在 Parent 组件内使用状态。父级将回调传递给编辑器。编辑器将使用此回调通知 Parent 有一本新书。Parent 将增加状态并将该状态作为道具传递给 BookList。然后 BookList 会检查 useEffect 中的 props 是否发生了变化,并重新加载书籍列表。


这是一个最小的代码示例:


const Parent = () => {

  const [x, setX] = React.useState(0);

  const onNewBook = () => {

    setX(state => state+1);

  }

  return (

    <>

      <BookList x={X} />

      <Editor onNewBook={onNewBook} />

    </>

  )

}


const Editor = (props) => {

  onSave = () => {

    // Save the editor to the DB

    props.onNewBook();

  }

}


const BookList= (props) => {

  React.useEffect(() => {

    // Reload the list from DB

  }, [props.X])

}


查看完整回答
反对 回复 2022-06-16
  • 3 回答
  • 0 关注
  • 179 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号