Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我是否需要Redux在左侧显示ItemList,在右侧显示ItemContent?_Javascript_Reactjs_Redux_React Router - Fatal编程技术网

Javascript 我是否需要Redux在左侧显示ItemList,在右侧显示ItemContent?

Javascript 我是否需要Redux在左侧显示ItemList,在右侧显示ItemContent?,javascript,reactjs,redux,react-router,Javascript,Reactjs,Redux,React Router,我真的需要Redux来管理应用程序状态以实现这一点吗?如果没有-如何管理/实施和/或组件的路由和状态 我应该创建组件并嵌套其他组件吗 组件在哪里? 也许这就是HOC的情况? 什么是最好的 接近 要澄清应用程序结构,请参见以下图片: 当前案例和代码: 我的应用程序状态是从传递的,如果你的应用程序简单且小,你不需要使用redux。您可以使用组件状态来实现这一点。你应该从小处着手,只有当你的应用程序足够大时才使用redux 现在,您可以将主要状态保留在组件中,并根据从列表中单击的项目将所需数据传递给

我真的需要Redux来管理应用程序状态以实现这一点吗?如果没有-如何管理/实施和/或组件的路由和状态

我应该创建组件并嵌套其他组件吗 组件在哪里? 也许这就是HOC的情况? 什么是最好的 接近

要澄清应用程序结构,请参见以下图片:

当前案例和代码: 我的应用程序状态是从

传递的,如果你的应用程序简单且小,你不需要使用redux。您可以使用组件状态来实现这一点。你应该从小处着手,只有当你的应用程序足够大时才使用redux

现在,您可以将主要状态保留在组件中,并根据从列表中单击的项目将所需数据传递给组件。范例

class ItemList extends Component {
  constructor(props) {
    super(props);
    this.state = {
     ...
     // you can keep your data here like
     // headings and data for the item content
    }
  }

  .
  .
  .
  // your methods
  .
  .
  .
  render() {
    const itemList = //map your list here and
    // provide a click event which will
    // render the respective <ItemContent />
    // may be using an id or some index of the array
    // depends how you want your data structure to be.
    return(
      {itemList}
      // based on which item from the list is clicked
      // you can pass different heading and state
      <ItemContent heading={...} data={...} />
    );
  }
}
编辑:代码中的更改

class ExpenseList extends Component {

  constructor(props) {
    super(props);
    this.state = {
      currentItemId = this.props.expenses[0].uid
    }
  }

  handleItemClick = (e) => {
    const uid = e.target.id;
    this.setState({ currentItemId: uid });
  }

  details = () => {
    const { expenseList } = this.props.expenses;
    const [ expense ] = expenseList.filter(expense => {
      return expense.uid === this.state.currentItemId;
    });
    return (
      <div>
        <ExpenseDetails expenseProps={expense} />
      </div>
    )
  }

  render () {
    const { expenseList } = this.props.expenses;

    const list = expenseList.map(expense =>
        <Segment clearing key={expense.uid} >
          <a href="#" id={expense.uid} onClick={this.handleItemClick}>
            {expense.createdAt}
          </a>
          <Button floated='right'>
            Preview / Print
          </Button>
        </Segment>
    )

    return (
      <Grid celled='internally'>
        <Grid.Row>
          <Grid.Column width={5}>
            <div>
              <h1>Your Expense List:</h1>
              <Button onClick={this.props.loadSamples}>Load Sample Expenses</Button>
              <Segment.Group raised>
                {list}
              </Segment.Group>
            </div>

          </Grid.Column>
          <Grid.Column width={11}>
            <Segment>
              {details()}
            </Segment>
          </Grid.Column>
        </Grid.Row>
      </Grid>
    )
  }
}

注意:我还没有测试过它。

对于一个简单的应用程序,我建议你避免重复使用,尤其是如果你是新手。我会使用react路由器,为每个具有不同url的“屏幕”创建一个组件。将状态存储在该屏幕中,并使所有其他组件在其数据和操作中使用道具

例如:

import React, { Component } from 'react';
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link,
} from 'react-router-dom'

import './App.css';

class ExpenseList extends Component {
    render () {
      const {expenses, selectExpense} = this.props;
      return (
        <div>{expenses.map(expense => (
          <div key={expense.id}>
            <h5>{expense.title}</h5>
            <button onClick={selectExpense(expense)}>View Details</button>
          </div>
        ))}</div>
      )
    }
  }

class ExpenseDetail extends Component {
    render () {
      const {expense} = this.props;
      return (
      <div>
        <h1>{expense.title}</h1>
        <p>${expense.amount}</p>
      </div>
      )
    }
  }



class ExpenseScreen extends Component {
  state = {expenses: [], selectedExpense: null}

  loadSamples = () => {
    // fetch from backend here

    this.setState({expenses: [
      {id: 1, title: "Expense 1", amount: 1},
      {id: 2, title: "Expense 2", amount: 2},
      {id: 3, title: "Expense 3", amount: 3},
      {id: 4, title: "Expense 4", amount: 4},
    ]})
  }

  selectExpense = (expense) => (clickEvent) => {
    this.setState({selectedExpense: expense});
  }

  render() {
    return(
    <div className="expense-container">
        <Link to="/about">About</Link>
        <div className="left-col">
          <h1>Your Expense List:</h1>
          <button onClick={this.loadSamples}>Load Sample Expenses</button>
          <ExpenseList expenses={this.state.expenses} selectExpense={this.selectExpense} />
        </div>
        <div className="right-col">
        {this.state.selectedExpense && <ExpenseDetail expense={this.state.selectedExpense} />}
  </div>
  </div>);
  }
}


 const About = () => (
    <div>
      <h2>About</h2>
      <Link to="/">Home</Link>
    </div>
  )

class App extends Component {
  render() {
    return (
      <div className="App">
        <Router>
          <Switch>
          <Route path="/" exact component={ExpenseScreen} />
          <Route path="/about" component={About} />
          </Switch>
        </Router>
      </div>
    );
  }
}

export default App;

谢谢你的回答。你能给我看看你的代码吗?如果两个组件对应于不同的URL,您如何在一个屏幕上呈现它们?正如我在帖子中所问的,您是否建议我应该创建组件并在其中嵌套其他组件?您是否也可以更正我发布的代码?我尝试用你的解决方案来解决编译问题,但没有成功。我只想看看和理解我的代码和react-router的案例。谢谢你的解决方案!我一直在看react路由器的例子,但仍然不知道如何调整它以适应我的情况。我必须把所有的道具都传给我的组件。不仅仅是身份证。非常感谢,你能帮我完成那个onClick活动吗?如何使用onClick传递道具?用最新的更新了我的帖子code@karolis2017更新了我的anwser。检查它是否适合你。
import React, { Component } from 'react';
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link,
} from 'react-router-dom'

import './App.css';

class ExpenseList extends Component {
    render () {
      const {expenses, selectExpense} = this.props;
      return (
        <div>{expenses.map(expense => (
          <div key={expense.id}>
            <h5>{expense.title}</h5>
            <button onClick={selectExpense(expense)}>View Details</button>
          </div>
        ))}</div>
      )
    }
  }

class ExpenseDetail extends Component {
    render () {
      const {expense} = this.props;
      return (
      <div>
        <h1>{expense.title}</h1>
        <p>${expense.amount}</p>
      </div>
      )
    }
  }



class ExpenseScreen extends Component {
  state = {expenses: [], selectedExpense: null}

  loadSamples = () => {
    // fetch from backend here

    this.setState({expenses: [
      {id: 1, title: "Expense 1", amount: 1},
      {id: 2, title: "Expense 2", amount: 2},
      {id: 3, title: "Expense 3", amount: 3},
      {id: 4, title: "Expense 4", amount: 4},
    ]})
  }

  selectExpense = (expense) => (clickEvent) => {
    this.setState({selectedExpense: expense});
  }

  render() {
    return(
    <div className="expense-container">
        <Link to="/about">About</Link>
        <div className="left-col">
          <h1>Your Expense List:</h1>
          <button onClick={this.loadSamples}>Load Sample Expenses</button>
          <ExpenseList expenses={this.state.expenses} selectExpense={this.selectExpense} />
        </div>
        <div className="right-col">
        {this.state.selectedExpense && <ExpenseDetail expense={this.state.selectedExpense} />}
  </div>
  </div>);
  }
}


 const About = () => (
    <div>
      <h2>About</h2>
      <Link to="/">Home</Link>
    </div>
  )

class App extends Component {
  render() {
    return (
      <div className="App">
        <Router>
          <Switch>
          <Route path="/" exact component={ExpenseScreen} />
          <Route path="/about" component={About} />
          </Switch>
        </Router>
      </div>
    );
  }
}

export default App;