Состояние set не обновляет состояние

Я пытаюсь использовать хук состояния в своем приложении для реагирования.

Но setTodos ниже, похоже, не обновляет todos
ссылка на мою работу: https://kutt.it/oE2jPJ ссылка на гитхаб: https://github.com/who-know-cg/Todo-реагировать

import React, { useState } from "react";

import Main from "./component/Main";

const Application = () => {
  const [todos, setTodos] = useState([]);

  // add todo to state(todos)
  const addTodos = message => {
    const newTodos = todos.concat(message);
    setTodos(newTodos);
  };

  return (
    <>
      <Main
        addTodos = {message => addTodos(message)}
      />
    </>
  );
};

export default Application;

И в моем main.js

const Main = props => {
  const input = createRef();
  return (
    <>
      <input type = "text" ref = {input} />
      <button
        onClick = {() => {
          props.addTodo(input.current.value);
          input.current.value = "";
        }}
      >
        Add message to state
      </button>
    </>
  );
};

Я ожидаю, что каждый раз, когда я нажимаю кнопку, будут выполняться setTodos() и getTodos(), и сообщение будет добавлено в массив todos.

Но оказывается состояние не изменилось. (тем не менее, оставайтесь в пустом массиве по умолчанию)

Вы уверены, что проблема getTodo() решена? successAlert() работает?

adesurirey 13.07.2019 15:28

поскольку вы не отображаете задачи внутри рендеринга вашего компонента, как вы можете определить, что ваше состояние не было обновлено?

Olivier Boissé 13.07.2019 16:01

Я пытаюсь запустить console.info(todos), может ли он показать todos?

Anmicius 13.07.2019 16:52

я попробовал ваш код github, и кажется, что он добавляет элементы в todos. так как вы можете сказать, что сообщение не добавляется в todos?

Amit Chauhan 13.07.2019 17:04
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
4
116
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вам не нужно передавать сообщение в качестве параметра в Main, просто имя функции.

<Main addTodos = {addTodos} />

Спасибо, я попробовал этот метод, но он все еще не работает ТАТ. Получается вот так (попробуйте два раза добавить todo кнопкой +) kutt.it/4UUcGX

Anmicius 13.07.2019 15:47
this ключевое слово не будет работать так как он заявлен как функциональный компонент, можно было прямо написать addTodos = {addTodos}
Olivier Boissé 13.07.2019 15:58
Ответ принят как подходящий

Если вы хотите обновить состояние родительского компонента, вы должны передать функцию от родительского к дочернему компоненту.

Вот очень простой пример, как обновить состояние с помощью хука из дочернего (основного) компонента.

С помощью кнопки из дочернего компонента вы обновляете состояние родительского (приложения) компонента.

const Application = () => {
  const [todos, setTodos] = useState([]);

  const addTodo = message => {
    let todosUpdated = [...todos, message];
    setTodos(todosUpdated);
  };
  return (
    <>
      <Main addTodo = {addTodo} />
      <pre>{JSON.stringify(todos, null, 2)}</pre>
    </>
  );
};

const Main = props => {
  const input = createRef();
  return (
    <>
      <input type = "text" ref = {input} />
      <button
        onClick = {() => {
          props.addTodo(input.current.value);
          input.current.value = "";
        }}
      >
        Add message to state
      </button>
    </>
  );
};

Демо здесь: https://codesandbox.io/s/silent-cache-9y7dl

Спасибо, я пытался использовать это в своем коде. но получается вот так (будет console.info(todos) после addTodos ) kutt.it/oE2jPJ ( º﹃º ) что происходит с моим приложением

Anmicius 13.07.2019 16:29

Попробуйте свой собственный код, мой был просто в качестве примера, чтобы вы лучше поняли, как работает хук setState, просто убедитесь, что вы используете <Main addTodos = {addTodos} />.

Janiis 13.07.2019 16:37

Если у вас есть код в репозитории git, вы можете добавить ссылку в свой вопрос, чтобы мы могли лучше понять, что происходит в вашем приложении.

Janiis 13.07.2019 16:39

спасибо за ваш совет, я добавил его к вопросу. github.com/who-know-cg/Todo-реагировать

Anmicius 13.07.2019 17:01

Ну проблема не в добавлении элемента :) Я разветвлю ваше приложение и исправлю.

Janiis 13.07.2019 17:21

Проблема была с удалением предметов. 1. Вы запускаете rmTodos при каждом рендере. Исправление заключалось в использовании функции стрелки. 2. Используйте фильтр для удаления состояния формы элементов вместо среза. Вот исправленная версия вашего кода - codeandbox.io/s/todo-реагировать-m5g0h Если это решение работает для вас, выберите мой ответ в качестве решения. Спасибо.

Janiis 13.07.2019 17:29

В Application.jsx:

Вы можете просто передать ссылку на addTodos здесь. Имя слева может быть каким угодно.

  <Main addTodos = {addTodos} />

В Main.jsx:

Так как getTodo возвращает обещание, все, что разрешает это обещание, будет вашим ожидаемым сообщением.

Вы передаете addTodos в качестве реквизита.

<Main
    addTodos = {message => addTodos(message)}
/>

Однако в дочернем компоненте вы получаете доступ с помощью

props.addTodo(input.current.value);

Должно быть addTodos.

props.addTodos(input.current.value);

Другие вопросы по теме