反应& React-Router& Redux渲染组件

时间:2016-10-07 03:23:33

标签: reactjs redux react-router react-redux

我有一个简单的应用程序。它有两个组成部分:

  • 商品 - 它只是从商店中呈现商品
  • AddItem - 只是将商品添加到商店

问题是:为什么当我提交 AddItem 组件的形式时,会再次安装此组件?如果我不调用 addItem 函数,则不会重新呈现 AddItem 。有什么想法吗?

Live example on WebpackBin

这是应用

import React, { Component } from 'react';
import { BrowserRouter, Match, Link, Redirect, browserHistory } from 'react-router';
import { Provider, connect } from 'react-redux';
import { createStore, bindActionCreators } from 'redux';
import { render } from 'react-dom';

// ACTIONS
const add = (item) => {
  return {
    type: 'ADD',
    payload: item
  }
};

// REDUCER
const initialState = {
  items: [
    'hello',
    'world'
  ]
};

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case 'ADD': {
      return { items: [...state.items, action.payload] };
    }

    default : {
      return state;
    }
  }
}

// STORE
const store = createStore(reducer);

// ADD ITEM
class AddItem extends Component {
  constructor(props) {
    super(props);

    this.state = {
      foo: 'bar'
    };
  }

  componentDidMount() {
    console.log('mount AddItem');
  }

  onSubmit(event) {
    event.preventDefault();

    this.props.addItem(this.itemTitle.value);
    this.form.reset();

    this.setState({
      foo: 'asd'
    });
  }

  render() {
    return (
      <div>
        <form onSubmit={::this.onSubmit} ref={node => this.form = node}>
          <div>
            <label htmlFor="item-title">Item</label>
          </div>
          <div>
            <input id="item-title" type="text" defaultValue="baz" ref={node => this.itemTitle = node}/>
          </div>
          <input type="submit" value="Add" />


          <div>
            {this.state.foo}
          </div>
        </form>

        <button>Click</button>
      </div>
    );
  }
}

// ITEMS
class Items extends Component {
  render() {
    return (
      <ul>
        {
          this.props.items.map(item => {
            return <li key={item}>{item}</li>;
          })
        }
      </ul>
    );
  }
}

// LAYOUT
class Layout extends Component {
  render() {
    const MatchWithProps = ({component:Component, ...rest}) => {
      <Match {...rest} render={() => (
        <Component {...this.props} />
      )}/>
    };

    return (
      <BrowserRouter>
        <div>
          <a href="/">Reload</a>
          <br />
          <Link activeOnlyWhenExact activeClassName="active" to="/">Items</Link>
          <Link activeClassName="active" to="/add">Add Item</Link>
          <hr />
          <Match exactly pattern="/" render={() => <Items {...this.props} /> } />
          <Match exactly pattern="/add" component={() => <AddItem addItem={this.props.itemActions.add} />} />
        </div>
      </BrowserRouter>
    );
  }
}

const mapStateToProps = (state) => {
  return {
    items: state.items
  };
}

const itemActions = { add };

const mapDispatchToProps = (dispatch) => {
  return {
    itemActions: bindActionCreators(itemActions, dispatch)
  };
}

const ConnectedLayout = connect(mapStateToProps, mapDispatchToProps)(Layout);

// PROVIDER
const provider = (
  <Provider store={store}>
    <ConnectedLayout />
  </Provider>
);

render(provider, document.querySelector('#react-container'));

0 个答案:

没有答案