在React组件之间移动数据

时间:2019-02-26 18:55:39

标签: javascript reactjs

因此,我试图将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;

3 个答案:

答案 0 :(得分:0)

您无法访问类似的方法。您需要将方法作为道具传递,并在孩子中使用它。

<Sidebar getNotesRows={this.getNotesRows} />

并在补充工具栏中使用

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

答案 1 :(得分:0)

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

在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>
  );
}

答案 2 :(得分:0)

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