React-Redux - 显示和隐藏组件

时间:2017-01-25 21:44:28

标签: reactjs redux

目标是当我将鼠标悬停在导航栏上的链接上时,我需要显示一个Component调用ProductDescription,并在鼠标未结束时隐藏该组件。

我有一个例子

https://www.dkny.com/ba/

目标是制作类似的东西。

app.js

import React, { Component } from 'react';
import PaginaInicial from '../containers/index';
import ListaJogos from '../containers/lista_jogos';
import ListaMusicas from '../containers/lista_musicas';
import NavBar from '../containers/menu';
import ProductDescription from '../containers/produto';


export default class App extends Component {
render() {
return (
    <div>
        <NavBar />
        <ProductDescription />
    </div>
);
}
}

导航栏组件

import React, { Component } from 'react';

class NavBar extends Component{



render(){
    return (
        <div>
            <ul>
                <li><a href="#">Link 1</a></li>
            </ul>
        </div>
    )
}

}

export default NavBar;

ProductDescription组件

import React, { Component } from 'react';

class Produto extends Component{

render(){

    return(

        <div>Some Product Description</div>

    )
}

}


export default ProductDescription;

动作index.js

function mostrarProduto(product) {
 return {
   type: 'SHOW_PRODUCT',
   payload: product
 }
}

function esconderProduto(product) {
 return {
  type: 'HIDE_PRODUCT',
  payload: product
 }
}

产品减速机

const productReducer = (state = null, action) => {
  switch (action.type) {
    case 'SHOW_PRODUCT':
      return action.payload;
    case 'HIDE_PRODUCT':
      return null;
    default:
      return state;
  }
}

我不知道我必须在组件中做什么,我知道我必须发送动作,但我很困惑,我需要一些帮助,谢谢。

2 个答案:

答案 0 :(得分:2)

我将假设您将悬停在导航栏项目上,并且该项目需要显示在ProductDescription中,这很好地接受空参数。

您需要将Navbar组件连接到redux存储(或者更好,创建连接到redux存储的导航栏“智能”容器)并绑定您的操作。

import React from 'react';
import { connect } from 'react-redux';

import { mostrarProduto, esconderProduto } from 'actions/index.js';

export class Navbar extends React.Component {

    constructor(props) {
        super(props);
        this.showProduct = this.showProduct.bind(this);
        this.hideProduct = this.hideProduct.bind(this);
    }

    showProduct() {
        // Bind object however you like
        this.props.mostrarProduto(productObjHere);
    }

    hideProduct() {
        // Bind object however you like
        // Also, if only want to show a single product on mouse over,
        // you don't need to pass product object; your reducer also returns null
        // for this one.
        this.props.esconderProduto(productObjHere);
    }

    render() {
        return (
            <ul>
                <li>
                    <a href="#" onMouseOver={this.showProduct} onMouseOut={this.hideProduct}>
                        Link #1
                    </a>
                </li>
            </ul>
        );
    }

}

const { func } = React.PropTypes;

Navbar.propTypes = {
    mostrarProduto.isRequired,
    esconderProduto.isRequired
};

export default connect(
    () => {},
    { mostrarProduto, esconderProduto }
)(Navbar);

您将操作传递给redux connect并将get映射到您的props中。这样,您就可以使用您的动作创建者从道具中发送这些动作。

然后在“产品说明”中,将状态映射到prop(无操作)并显示数据。

import React from 'react';
import { connect } from 'react-redux';

export class ProductDescription extends React.Component {

    render() {
        return (
            <div>{this.props.hoveredProduct}</div>
        );
    }

}

const { func } = React.PropTypes;

const mapStateToProps = state => ({
    hoveredProduct: state.product
});
// I used different names for state and mapped prop, so the declaration
// is clear

export default connect(
    mapStateToProps,
    null
)(ProductDescription);

答案 1 :(得分:2)

首先,您需要使用onMouseOver组件中的onMouseLeaveNavBar功能,更具体地说,您需要使用它的HTML标记英寸

<div onMouseOver={/* dispatch action here */} onMouseLeave={/* dispatch action here */}>
  <ul>
      <li><a href="#">Link 1</a></li>
  </ul>
</div>

当输入div时,该功能会触发一次。如果鼠标离开此div并再次输入,则该功能将再次触发。

您可以通过不同的方式在此处发送操作。根据您提供的代码,您可以直接在组件中执行此操作:

<div onMouseOver={this.props.dispatch(mostrarProduto())} onMouseLeave={this.props.dispatch(esconderProduto())}>

或者,如果您使用Redux中的mapDispatchToProps,您可以将上述内容简化为:

<div onMouseOver={this.props.mostrarProduto()} onMouseLeave={this.props.esconderProduto()}>

您当前的操作使用payload键,但如果ProductDescription是您要隐藏/展示的唯一组件,则可以省略它,因为您不需要识别要隐藏的产品/显示反正只有一个。然后,您只需要调度类型:

function mostrarProduto() {
  return {
    type: 'SHOW_PRODUCT'
  }
}

function esconderProduto() {
  return {
   type: 'HIDE_PRODUCT'
  }
}

在reducer中,您可以将默认状态设为false,以便ProductDescription不会在渲染开始时显示。当调度上述操作时,reducer会相应地处理类型:

const productReducer = (state = false, action) => {
  switch (action.type) {
    case 'SHOW_PRODUCT':
      return true;
    case 'HIDE_PRODUCT':
      return false;
    default:
      return state;
  }
}

现在ProductDescription需要以某种方式阅读此状态以及您使用Redux中的connectmapStateToProps函数的位置:

const mapStateToProps = (state) => ({
  shouldBeVisible: state.shouldBeVisible //<----- replace `shouldBeVisible` with what ever you're setting in your state store. See `createStore` in the Redux docs for more info.
})

export default connect(mapStateToProps)(ProductDescription)

然后在ProductDescription中,您根据this.props.isVisible的布尔值渲染组件:

class ProductDescription extends React.Component {
  //...

  render() {
      if (this.props.shouldBeVisible) {
        return <div>Some Product Description</div>
      } else { // shouldBeVisible is false, then show nothing.
        return null
      }
  }
}

const mapStateToProps = (state) => ({
  shouldBeVisible: state.shouldBeVisible
})

export default connect(mapStateToProps)(ProductDescription)
相关问题