开发者问题收集

为什么此解构属性不起作用

2020-12-08
213

当我尝试在 booklis.jsx 中解构 Bookcontext 时,它不起作用,并且显示:

TypeError: Cannot destructure property 'books' of 'Object(...)(...)' as it is undefined.

bookcontext.jsx

// 功能组件

import { createContext, useState } from "react";

export const Bookcontext = createContext();


const BookcontextProvider = (props) => {
    const [books, setBook] = useState([
        { title: ' Name of the wind ', id: 1 },
        { title: ' Name of the Blind ', id: 2 },
        { title: ' Name of the Love', id: 3 },
        { title: ' Name of the Shine  ', id: 4 },
    ])
    return (
        <div>
            <BookcontextProvider value={{ books }}>
                {props.childrean}
            </BookcontextProvider>
        </div>
    );
};

export default BookcontextProvider;

booklis.jsx

import React, { useContext } from "react"; import { Themcontext } from "../Context/Themcontext"; import { Bookcontext } from "../Context/Bookcontext";

/// 如何在功能组件中使用上下文,解构方法是

const Booklis = () => {
  const { isLightThem, light, dark } = useContext(Themcontext);

  const { books, setbook } = useContext(Bookcontext);
  const theme = isLightThem ? light : dark;

  return (
    <div>
      <div
        className="book-list"
        style={{ color: theme.sintex, background: theme.bg }}
      >
        <ul>
          {books.map((boe) => {
            return (
              <li key={boe.id} style={{ background: theme.ui }}>
                {boe.title}{" "}
              </li>
            );
          })}
        </ul>
      </div>
    </div>
  );
};

export default Booklis;
2个回答

useContext(Bookcontext); 将返回您传递给提供程序的值。

因此,如果您的提供程序看起来像

<BookcontextProvider value={{ books }}>
       {props.childrean}
 </BookcontextProvider>

useContext 将仅返回书籍作为该对象的一部分..

您需要将 setBook 添加到值中,如下所示

<BookcontextProvider value={{ books, setBook }}>
       {props.childrean}
 </BookcontextProvider>
Moshe Sommers
2020-12-08

您有几个拼写错误,但其中最重要的是: childrean 。应该是 children

您没有从上下文提供程序返回正确的东西。

<BookcontextProvider value={{ books }}>
    {props.children}
</BookcontextProvider>

应该是

<Bookcontext.Provider value={{ books }}>
    {props.children}
</Bookcontext.Provider>

最后,您没有将 Booklist 组件与您的提供程序包装在一起,您应该这样做。

const Bookcontext = React.createContext();

const BookcontextProvider = (props) => {
  const [books, setBook] = React.useState([
    { title: " Name of the wind ", id: 1 },
    { title: " Name of the Blind ", id: 2 },
    { title: " Name of the Love", id: 3 },
    { title: " Name of the Shine  ", id: 4 }
  ]);
  
  return (
    <div>
      <Bookcontext.Provider value={{ books }}>
        {props.children}
      </Bookcontext.Provider>
    </div>
  );
};

function Booklist() {
  const { books } = React.useContext(Bookcontext);

  return (
    <div>
      <div className="book-list">
        <ul>
          {books.map((book) => {
            return <li key={book.id}>{book.title} </li>;
          })}
        </ul>
      </div>
    </div>
  );
};

function Main() {
  return (
    <BookcontextProvider>
      <Booklist />
    </BookcontextProvider>
  );
}

ReactDOM.render(
<Main />,
  document.getElementById("root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root" />

此外,如果您想更新书单,您应该通过上下文传递 setter 函数。

<Bookcontext.Provider value={{ books, setBooks }}>
const Bookcontext = React.createContext();

const BookcontextProvider = (props) => {
  const [books, setBook] = React.useState([
    { title: " Name of the wind ", id: 1 },
    { title: " Name of the Blind ", id: 2 },
    { title: " Name of the Love", id: 3 },
    { title: " Name of the Shine  ", id: 4 }
  ]);
  
  return (
    <div>
      <Bookcontext.Provider value={{ books, setBook }}>
        {props.children}
      </Bookcontext.Provider>
    </div>
  );
};

const Booklist = () => {
  const { books, setBook } = React.useContext(Bookcontext);
  const [inputValue, setInputValue] = React.useState("");

  function addBook() {
    setBook((prev) => [...prev, { id: prev.length + 1, title: inputValue }]);
    setInputValue("");
  }

  return (
    <div>
      <div className="book-list">
        <ul>
          {books.map((book) => {
            return <li key={book.id}>{book.title} </li>;
          })}
        </ul>
        <div>
          <input
            value={inputValue}
            onChange={(e) => setInputValue(e.target.value)}
          />{" "}
          <button onClick={addBook}>Add new book</button>
        </div>
      </div>
    </div>
  );
};

function Main() {
  return (
    <BookcontextProvider>
      <Booklist />
    </BookcontextProvider>
  );
}

ReactDOM.render(
<Main />,
  document.getElementById("root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root" />
devserkan
2020-12-08