如何在 React.js 中将数据从子组件传递到父组件

How to pass data from a child component to a parent component in React.js

我想将动态 pdf 文件从 BooksList 组件传递到 Link 组件 react-router-dom 这样当我点击 BooksList 组件时 Link 一个pdf文件会传给Link,然后Link会转发这个pdf 文件到将呈现此 pdf 文件的 PDFViewer 组件。如果不可能,请您建议我可以用来实现此功能的方法。传递任何数据之前的代码示例如下:

<Link to="/pdf_viewer">
    <BooksList></BooksList>
</Link>

<Route path="/pdf_viewer">
    <PDFViewer></PDFViewer>
</Route>

书籍列表

export class BooksList extends Component {
    render() {
        return this.props.books.map((book)=> (
          //Here there is book info rendered from props
          //PDF file is an attribute in book eg. book.pdf_file
          <div>Title: {book.book_title}</div>
        ));
    }
}

export default BooksList

PDFViewer

export class PDFViewer extends Component {
    
    constructor(props){
        super(props);
        const { state: { pdfFile } } = this.props.location;
    }

    render() {
        return (
            <div key={book._id} className="pdfViewer">
                <embed src={ `data:application/pdf;base64, ${this.state}` } width="100%" height="600px"></embed>
            </div>
        )
    }

}

export default PDFViewer

UnLinkedBooksList

export class UnLinkedBooksList extends Component {
    viewPDFHandler = pdfFile => {
        const {history} = this.props;
        history.push({
            pathname: "/pdfviewer",
            state: {
                pdfFile
            }
        });
    }
    render() {
        return this.props.books.map((book)=> (
            <div>
                <button type="button" onClick={()=> this.viewPDFHandler(book.pdf_file_byte["$binary"])}>View PDF</button>
            </div>
        ));
    }
}

const BooksList = withRouter(UnLinkedBooksList);

export default UnLinkedBooksList

应用程序

export class App extends Component {

  state = {
    books: []
  }

  componentDidMount(){
    axios.get("http://127.0.0.1:5000/get_all_books").then(res=>this.setState({books:res.data.all_books}))
  }
  render() {
    return (
      <Router>
        {/* Index Page */}
        <Route exact path="/">
          <div className="App">
            <SearchBar></SearchBar>
            <div className="row p-10">
              <div className="col-lg-6">
                <Link to="/pdf_viewer" className="text-decoration-none">
                  <BooksList books={this.state.books}></BooksList>
                </Link>
              </div>
            </div>        
          </div>
        </Route>

        {/* PDF Viewer Page */}
        <Route path="/pdf_viewer" className="text-decoration-none">
          <PDFViewer></PDFViewer>
        </Route>

       </Router>
    )
  }
}

export default App

您可以执行以下操作;

...
const [url, setURL] = useState("");
const setPDFurl = (link)=>{
   setURL(link);
}
<Link to={`/pdf_viewer/${url}`}>
  <BooksList getURL = {setPDFurl }></BooksList>
</Link>
...

在您的 Booklist 组件上,

 export default function booklist(props){
   ...
    const [url, setUrl] = useState("");
   ...
    props.getURL(url)
   ...
}

希望它有意义。

BooksList 中公开路由上下文中的 history 对象,并为每本映射的书添加一个处理程序,以将 PDF 文件引用作为路由转换负载传递。由于 BooksList 是一个基于 class 的组件并且不是由 Roiute 呈现的(它可能应该是,顺便说一句 ),使用 withRouter Higher Order Component to decorate and inject route props, (history, location, match).

class UnlinkedBooksList extends Component {
  viewPdfHandler = pdfFile => {
    const { history } = this.props;
    history.push({
      pathname: "/pdf_viewer",
      state: {
        pdfFile
      }
    });
  };

  render() {
    return this.props.books.map((book)=> (
      //Here there is book info rendered from props
      //PDF file is an attribute in book eg. book.pdf_file
      ...
      <button
        type="button"
        onClick={() => viewPdfHandler(book.pdf_file)}
      >
        View PDF
      </button>
    ));
  }
}

const BooksList = withRouter(UnlinkedBooksList);

export default BooksList;

在 App 中,默认导入 BooksList,这是将具有 location 属性的链接组件。

import BooksList from './path/to/BooksList';

在接收端你可以提取路由状态。在 component 道具上渲染 PDFView 以便它也接收路由道具,具体来说,location 以便它可以访问路由状态。

<Route path="/pdf_viewer" component={PDFViewer} />

在 PDFViewer 中,从 location 对象访问 pdfFile

const { state: { pdfFile } } = this.props.location;