Как изменить состояние функционального компонента из другого компонента, который не является родительским или дочерним? - PullRequest
0 голосов
/ 01 мая 2020

В моем коде у меня есть функциональный компонент, который отображает список пользователей в базе данных, используя нумерацию страниц «загрузить еще», а компонент, который отображает сведения о пользователе наряду с некоторыми действиями, когда вы нажимаете на них, представляет собой список. По аналогии с файловым менеджером. Одним из таких действий является удаление пользователя. Когда вы делаете это, список пользователей не обновляется, и если вы щелкаете по только что удаленному пользователю, появляется ошибка выполнения, поскольку код пытается использовать информацию из нулевого объекта. Каков наилучший способ обновления компонента списка после удаления пользователя без использования компонентов класса?

Приложение. js - родительский элемент списка и компонентов сведений

<BrowserRouter>
  <div id = "app">
    <div className = "section sectionTop">
      <Route path = "/" component = {BaseTop}/>
    </div>
    <div className = "Main">
      <div className = "section sectionMain sectionLeft">
      <Route path = "/" component = {BaseLeft}/>
      </div>
      <div className = "section sectionMain sectionCenter">
        <Route path = "/" exact component = {BaseCenter}/>
        <Route path = "/listusers" component = {UserList}/>
      </div>
      <div className = "section sectionMain sectionRight">
        <Route path = "/" exact component = {BaseRight}/>
        <Route path = "/adduser" component = {UserAdd}/>
        <Route path = "/listusers/:id" component = {UserInfo}/>
      </div>
    </div>
  </div>
</BrowserRouter>

UserList. js - список пользователей

const [users, setUsers] = useState ([]);
const [page, setPage] = useState (0);

useEffect
(
    () =>
    {
        setPage (page+1);
    },
    []
);

useEffect
(
    () =>
    {
        try
        {
            const runEffect = async () =>
            {
                const response = await api.get
                (
                    `/users?page=${page}`
                );
                setUsers ([...users, ...response.data.docs]);
            }
            runEffect();
        }
        catch (error)
        {
            console.log (error);
        }
    },
    [page]
);

return (
    <div className = "userListArea">
        {
            users.map
            (
                (user, index) =>
                {
                    return (
                        <div key = {index} className = "user">
                            <Link key = {index} to = {`/listusers/${user._id}`}>
                                <button
                                className = "buttonUser"
                                key = {index}>
                                    {user.name}
                                </button>
                            </Link>
                        </div>
                    )
                }
            )
        }
        <button
        className = "buttonLoadMore"
        onClick = {() => setPage (page+1)}>
            Carregar mais
        </button>
    </div>
)

UserInfo. js - данные пользователя

const [user, setUser] = useState ({});
const [_id, set_id] = useState ("");

useEffect
(
    () =>
    {
        if (user.hasOwnProperty ("_id") === false)
        {
            set_id (match.params.id);
        }
        else
        {
            if (user._id !== match.params.id)
            {
                set_id (match.params.id);
            }
        }
        const runEffect = async () =>
        {
            const response = await api.get
            (
                "/searchuser",
                {
                    params:
                    {
                        _id
                    }
                }
            )
            if (user.hasOwnProperty ("name") === false)
            {
                setUser (response.data);
            }
            else
            {
                if (user.name !== response.data.name)
                {
                    setUser (response.data);
                }
            }
        }
        runEffect();
    }
);

async function handleDeleteUser (_id)
{
    if (window.confirm(`Você realmente deseja remover o usuário ${user.name}?`))
    {
        const response = await api.delete
        (
            "/users",
            {
                params:
                    {
                        _id
                    }
            }
        );
        if (response.data._id === _id)
        {
            window.alert(`O usuário ${user.name} foi excluído.`);
        }
    }
}

return (
    <div className = "userInfoArea">
        <div className = "name">{user.name}</div>
        <div className = "email">{user.email}</div>
        <button className = "buttonEdit">Editar</button>
        <Link to = "/listusers">
            <button
            className = "buttonDelete"
            onClick = {() => handleDeleteUser (user._id)}
            >
                Excluir
            </button>
        </Link>
    </div>
)

1 Ответ

0 голосов
/ 02 мая 2020

Нельзя обновить состояние компонента, который не является родительским или дочерним, без использования внешнего решения для управления состоянием, такого как Redux или новый useContext api / hook. Эти библиотеки включают перемещение всех состояний отдельных компонентов в более крупное централизованное глобальное состояние, которое может быть обновлено и доступно всем компонентам.

...