在反应组件之间移动数据

问题描述 投票:0回答:3

所以我试图将我的App.js上的组件分解为一个较小的组件,即我的Sidebar.js。我拿了一小部分代码并把它放在自己的Sidebar.js文件中,但无论我尝试过什么,我都无法从App.js调用我的函数getNotesRows(),而无法找到它或this.states .notes未定义。我只是希望它来回发送代码。这是一个演示应用程序,所以我知道它不是最实用的。

import React, { Component } from "react";
import classNames from "classnames";
import logo from "./logo.svg";
import checkMark from "./check-mark.svg";
import "./App.css";
import Sidebar from "./components/Sidebar.js";

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      notes: [],
      currentNoteIndex: 0
    };
    this.markAsRead = this.markAsRead.bind(this);
    this.selectNote = this.selectNote.bind(this);
    console.log("Test started 2.25.19 19:23");
  }
  
  componentWillMount() {
    fetch('/notes')
	.then(response => response.json())
    .then(
		notes => {
			this.setState({
				notes: notes,
				currentNoteIndex: 0
			})
		}
	)
	.catch(
		error => {
			console.log('Ooops!');
			console.log(error);
		}
	);
  }

  
  markAsRead() {
    this.setState(currentState => {
      let marked = {
        ...currentState.notes[currentState.currentNoteIndex],
        read: true
      };
      let notes = [...currentState.notes];
      notes[currentState.currentNoteIndex] = marked;
      return { ...currentState, notes };
    });
  }

  
  selectNote(e) {
    this.setState({ currentNoteIndex: parseInt(e.currentTarget.id, 10) });

  }

  getTotalUnread() {
    let unreadArray = this.state.notes.filter(note => {
    return note.read === false;
    })
    return unreadArray.length;
    }

    getNotesRows() {
    
      return this.props.notes.map(note => (
        <div
          key={note.subject}
          className={classNames("NotesSidebarItem", {
            selected:
              this.props.notes.indexOf(note) === this.props.currentNoteIndex
          })}
          onClick={this.selectNote}
          
          id={this.props.notes.indexOf(note)}
        >
          <h4 className="NotesSidebarItem-title">{note.subject}</h4>
          {note.read && <img alt="Check Mark" src={checkMark} />}
        </div>
      ));
    }

  // TODO this component should be broken into separate components.

  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Notes Viewer Test App</h1>
          <div>
            Unread:
            <span className="App-title-unread-count">
              {this.getTotalUnread()}
            </span>
          </div>
        </header>
        <div className="Container">
        <Sidebar />
        <section className="NoteDetails">
  {this.state.notes.length > 0 && (
    <h3 className="NoteDetails-title">
      {this.state.notes[this.state.currentNoteIndex].subject}
    </h3>
  )}
  {this.state.notes.length > 0 && (
    <p className="NoteDetails-subject">
      {this.state.notes[this.state.currentNoteIndex].body}
    </p>
  )}
  {this.state.notes.length > 0 && (
    <button onClick={this.markAsRead}>Mark as read</button>
  )}
  {this.state.notes.length <= 0 && (
    <p>
    No Notes!
    </p>
  )}
</section>
</div>
</div>
    );
  }
}

export default App;

上面是我的App.js,下面是我正在尝试创建的Sidebar.js

import React, { Component } from "react";
import "../App.css";
import App from "../App.js";


class Sidebar extends React.Component{
    constructor(props) {
        super(props);
    }
    render(){
        return (
            <section className="NotesSidebar">
                <h2 className="NotesSidebar-title">Available Notes:</h2>
                <div className="NotesSidebar-list">{App.getNotesRows()}</div>
            </section>
)}}

export default Sidebar;
javascript reactjs
3个回答
0
投票

你无法访问这样的方法。您需要将该方法作为道具传递并在孩子中使用它。

<Sidebar getNotesRows={this.getNotesRows} />

并在补充工具栏中使用

<div className="NotesSidebar-list">{this.props.getNotesRows()}</div>

0
投票

在侧边栏中,您尝试从App调用getNotesRows(),但补充工具栏不需要访问应用程序(您不必在Sidebar.js中导入App)。相反,您应该将功能从App传递给补充工具栏组件,并从补充工具栏的道具中引用它。

在App.js中,您需要绑定getNotesRows并将其传递给侧栏:

<Sidebar getNotesRows={ this.getNotesRows } />

然后在Sidebar.js中,您需要在渲染方法中引用getNotesRows

render() {
  const notes = this.props.getNotesRows();
  return (
    <section className="NotesSidebar">
      <h2 className="NotesSidebar-title">Available Notes:</h2>
      <div className="NotesSidebar-list">{ notes }</div>
    </section>
  );
}

0
投票

这里的问题似乎是你试图使用类函数作为静态属性,简单来说,当你将它导入侧边栏(?)时你没有初始化App类,因此没有找到静态函数在你的App类上,你可以调用App.getNotesRows(),也许你应该重新思考你的组件,并使用基于组合的编程方法而不是OO方法将它们分离在容器组件中。

© www.soinside.com 2019 - 2024. All rights reserved.