在Javascript / React

时间:2016-08-29 23:01:27

标签: javascript reactjs arguments

我想通过每个地图功能传递一个名为verified的道具,我很难设置它。

更新

verified传递给renderContinents可以正常工作,但是在向renderCountry添加参数时会这样:

  {continent.countries.map(renderCountry(null, verified))}

我的输出是空白的。不应该这样吗?

更新的代码:

  const renderCities = cities => {
    return (
      <div>
        <label>
          <input
              onChange={onChange}
              type="checkbox"/>
        {cities.name}
        </label>
      </div>
    );
  };

  const renderCountries = ({country, verified}) => {
    console.log("came to country");
    return (
      <div className="city-location"> 
        <label>
            <input
              onChange={onChange}
              type="checkbox"/>
          {country.name}
        </label>
        {country.cities.map(renderCities)}
      </div>
    ); 
  };



function onChange(e) {
  console.log('checkbox verified:', (e.target.verified));
}


class AreasComponent extends Component {
      constructor(props) {
        super(props);
        this.state = { 
        };
        this.renderContinents = this.renderContinents.bind(this);
    }

  componentWillMount() {
    this.props.fetchAllAreas(); 
  }

  renderContinents(verified, continent) {
    console.log("came to continent");
      return(
        <div className="continent-location">
          <label>
            <input
              onChange={onChange}
                type="checkbox"/>
             {continent.name}
          </label>

          {continent.countries.map(renderCountries(null, verified))}

        </div>
    )
  } 


  render() { 
    if (!this.props.verified || !this.props.areas) {
      return <div>Loading Areas...</div>
    }
    return(
        <div> 
          {this.props.areas.map(this.renderContinents.bind(this, this.props.verified))}
        </div>
      );
    }
}

function mapDispatchToProps(dispatch){
  return bindActionCreators({ fetchAllAreas, checkArea}, dispatch);
}


function mapStateToProps(state) {
  return { areas: state.areas.all,
           verified:state.areas.verified
  };
}


export default connect(mapStateToProps, mapDispatchToProps)(AreasComponent);

我的另一个问题是onChange(e)功能。它是全局的,所以当我点击任何复选框时它可以工作,但我想这样做,以便当点击onChange时,它可以接受一个参数并发送动作checkArea,这对我来说意味着它必须被绑定并且还应该作为参数提供。我试过这个:

  {this.props.areas.map(this.renderContinents.bind(this, this.props.verified, this.props.checkArea))} 

但它返回一个空白结果。是否可以将函数发送到map()参数中,是否有办法让renderCountry / renderCity与参数一起使用?

2 个答案:

答案 0 :(得分:5)

当你.bind参数时,这些参数成为传递给函数的第一个值。在查看console.log输出时,您应该已经注意到了。

即。当你做的时候

var bar = foo.bind(this, x, y);
bar(z);

您按此顺序获取值:

function foo(x, y, z) {}

您已在功能中切换参数的顺序:

renderContinent(checked, continent) {
  // ...
}

但是,您可以保留您拥有的代码。您不必将值传递给renderContinents

为了将其传递给renderContinents等,请.bind或将调用放在另一个函数中:

continent.countries.map(renderCountries.bind(null, verified))
// or
continent.countries.map(country => renderCountries(country, verified))

答案 1 :(得分:1)

事实上,renderCountry/renderCity使用onChange()动作调用checkArea的最简单方法是将它们放在AreasComponent内(即作为成员函数)。因此,他们可以同时访问onChangecheckArea

class AreasComponent extends Component {
    constructor(props) {
        super(props);
        this.state = {};
        this.onChange = this.onChange.bind(this);
    }

    componentWillMount() {
        this.props.fetchAllAreas();
    }

    onChange(e, type) {
        console.log('checkbox verified:', this.props.verified);
        // call checkArea() here with your parameters
        this.props.checkArea(type);
    }

    renderCities(cities) {
        return (
            <div>
                <label>
                    <input
                        onChange={e => this.onChange(e, 'city')}
                        type="checkbox"/>
                    {cities.name}
                </label>
            </div>
        );
    };

    renderCountries(country) {
        console.log("came to country");
        return (
            <div className="city-location">
                <label>
                    <input
                        onChange={e => this.onChange(e, 'country')}
                        type="checkbox"/>
                    {country.name}
                </label>
                {
                    country.cities.map(this.renderCities)
                }
            </div>
        );
    };

    renderContinents(continent) {
        console.log("came to continent");
        return(
            <div className="continent-location">
                <label>
                    <input
                        onChange={e => this.onChange(e, 'continent')}
                        type="checkbox"/>
                    {continent.name}
                </label>
                {
                    continent.countries.map(this.renderCountries)
                }
            </div>
        )
    }

    render() {
        if (!this.props.verified || !this.props.areas) {
            return <div>Loading Areas...</div>
        }
        return(
            <div>
                {
                    this.props.areas.map(this.renderContinents)
                }
            </div>
        );
    }
}

function mapDispatchToProps(dispatch){
    return bindActionCreators({ fetchAllAreas, checkArea}, dispatch);
}


function mapStateToProps(state) {
    return {
        areas: state.areas.all,
        verified: state.areas.verified
    };
}


export default connect(mapStateToProps, mapDispatchToProps)(AreasComponent);