反应:将数据从子组件传递到父组件不会更新父组件中的值

时间:2020-07-31 16:52:22

标签: reactjs state parent-child

//编辑-

这可能会帮助: Project Hatchways

发布链接- Issue

代码现在可以使用了,标记的结果仍然无法呈现结果。

我有一个呈现一些子代的组件App.js。其中之一是2个搜索栏。第二个搜索栏<head> <script src="https://use.fontawesome.com/releases/v5.0.8/js/all.js"> </head> 应该呈现标记创建的结果。我想做的是从标签所在的TagSearch传递数据,并将它们传递到App组件,以便将它们注入到我的Fuse实例中,以便对其进行搜索。我试图在App.js中创建一个函数Student,然后将其传递给Student.js,以便当用户搜索标签时在父级中更新标签。由于某种原因,我收到一个指出update不是函数的TypeError。

我放入控制台日志中以跟踪标签的显示位置。这些标签在Student.js中看起来完全正常,但是当我在App.js中进行控制台登录时,这些标签只是显示为一个空数组,这表明它们没有正确地从Student.js传递到App的组件树中。 js。

// App.js

update

// Student.js

import axios from "axios";
import Fuse from "fuse.js";
import Student from "./components/Student";
import Search from "./components/Search";
import TagSearch from "./components/TagSearch";
import "./App.css";

function App() {
  const [loading, setLoading] = useState(true);
  const [students, setStudents] = useState([]);
  const [query, updateQuery] = useState("");
  const [tags, setTags] = useState([]);
  const [tagQuery, setTagQuery] = useState("");
  console.log("tags from app: ", tags);

  const getStudents = async () => {
    setLoading(true);
    try {
      const url = `private url for assignment`;
      const response = await axios.get(url);
      setStudents(response.data.students);
      setLoading(false);
    } catch (err) {
      console.log("Error: ", err);
    }
  };

  const fuse = new Fuse(students, {
    keys: ["firstName", "lastName"],
    includeMatches: true,
    minMatchCharLength: 2,
  });

  const tagFuse = new Fuse(tags, {
    keys: ["text", "id"],
    includesMatches: true,
    minMatchCharLength: 2,
  });

  function handleChange(e) {
    updateQuery(e.target.value);
  }

  function handleTags(e) {
    setTagQuery(e.target.value);
  }

  const results = fuse.search(query);
  const studentResults = query ? results.map((s) => s.item) : students;

  const tagResults = tagFuse.search(tagQuery);
  const taggedResults = tagQuery ? tagResults.map((s) => s.item) : tags;

  const update = (t) => {
    t = tags; // changed this to make sure t is tags from this component's state
    setTags(t);
  };

  useEffect(() => {
    getStudents();
  }, []);

  if (loading) return "Loading ...";
  return (
    <div className="App">
      <main>
        <Search query={query} handleChange={handleChange} />
        <TagSearch query={tagQuery} handleTags={handleTags} />
        {studentResults &&
          studentResults.map((s, key) => <Student key={key} students={s} update={update} />)}
        {taggedResults &&
          taggedResults.map((s, key) => (
            <Student key={key} students={s} update={update} />
          ))}
      </main>
    </div>
  );
}

export default App;

1 个答案:

答案 0 :(得分:0)

请注意,每次在update中更新tags时,尝试调用Student函数。像这样:

const handleDelete = (i) => {
    const deleted = tags.filter((tag, index) => index !== i);
    setTags(deleted);
    update(deleted);
  };

  const handleAddition = (tag, i) => {
    let result = tags;
    result.push(tag);
    setTags(result);
    update(result);
  };

通过这种方式,每次在tags中更改Student时,都将更新App状态。

可以使用useEffect deps列表作为替代。在Student中,像这样修改useEffect

useEffect(() => {
    update(tags);
  }, [tags]);

这意味着,每次tags更新时,都会触发useEffect,并调用update函数。