如何通过功能设置道具

时间:2019-07-11 20:43:56

标签: javascript reactjs

我是React的新手,我知道这是一个小问题,但我不知道如何解决。

我需要做一个以上的心脏按钮,并将标记为paramether的道具isChecked更改为truefalse,因此按钮将从{{ 1}}到HeartNormal

代码无法执行此操作,因为每个按钮都需要分别在HeartFullHeartNormal之间进行更改。

HeartFull

import React, { Component } from 'react'; class Test extends Component { handleLike = props =>{ props.isCheck = true; } renderer(){ return( <div> <Heart isClicked={false} onClick={() => this.handleLike(this.props)}/> <Heart isClicked={false} onClick={() => this.handleLike(this.props)}/> <Heart isClicked={false} onClick={() => this.handleLike(this.props)}/> <Heart isClicked={false} onClick={() => this.handleLike(this.props)}/> <Heart isClicked={false} onClick={() => this.handleLike(this.props)}/> </div> ) } } function Heart(props){ const isClicked = props.isClicked; if(isClicked){ return <button onClick={props.onClick}><i className="fas fa-heart"></i></button> }else{ return <button onClick={props.onClick}><i className="far fa-heart"></i></button> } } export default Test; 中,还有另一个参数可以将喜欢的帖子的ID邀请到节点服务器,因为这是为我编写代码的理想结构。我希望有人能帮助我解决这个问题。

4 个答案:

答案 0 :(得分:2)

问题:您无法在React中分配道具,因为它们是只读的。更新道具的方法是更新父级发送到该组件的值。
含义<Test isCheck={/* change the value here */} />

解决方案:您可以使用React Hooks为每个单独的Heart组件使用状态。这样,每个Heart都将具有彼此独立的独立状态,并且Test组件将不需要跟踪每个状态。

这是更新的代码:

import React, { Component } from 'react';

class Test extends Component {
    renderer(){
        return(
            <div>
            <Heart/>
            <Heart/>
            <Heart/>
            <Heart/>
            <Heart/>
            </div>
        )
    }
}
function Heart(props){
    const [isClicked, setIsClicked] = useState(false);

    return (
        <button onClick={() -> setIsClicked(true)}>
            <i className={clicked ? "fas fa-heart" : "far fa-heart"}></i>
        </button>
    );
}
export default Test;

答案 1 :(得分:1)

您需要使Heart成为具有状态的组件,然后您拥有的每个Heart都会分别具有状态并呈现不同的状态

import React, { Component } from 'react';

class Test extends Component {
//should be render
    render(){
        return(
            <div>
              <Heart isClicked={false} />
              <Heart isClicked={false} />
              <Heart isClicked={false} />
            </div>
        )
    }
}

class Heart extends Component {

    constructor(props){
        super(props)
        this.state = {
            clicked: this.props.isClicked
        }
    }

    handleClick = () => {
        this.setState({clicked: !this.state.clicked})
    }

    render(){
        const {clicked} = this.state
        return(<button onClick={() => this.handleClick()}>
                <i className={clicked ? "fas fa-heart" : "far fa-heart"}></i>
               </button>)
    }
}

export default Test;

答案 2 :(得分:0)

您需要在此处使用状态。您可以做的是将一个数组存储在Test组件的state中,该数组代表每个心脏,然后分别对其进行突变。

它看起来像这样:

class Test extends Component {
  constructor(props) {
    super(props);

    this.state = {
      hearts: [
        { liked: false },
        { liked: false },
        { liked: false },
        { liked: false },
        { liked: false }
      ]
    };
  }

  handleHeartClick(heartIndex) {
    let clickedHeart;

    this.setState({
      hearts: this.state.hearts.map((heart, index) => {
        if (index === heartIndex) {
          heart.isCheck = !heart.isCheck;
          clickedHeart = heart;
        }

        return heart;
      });
    });

    // Send your clickedHeart off to your node server, or whatever else you need with it
  }

  render() {
    const heartComponents = this.state.hearts.map((heart, index) => (
      <Heart isClicked={heart.isCheck} onClick={() => this.handleHeartClick(index)} />
    ));

    return (
      <div>
        {heartComponents}
      </div>
    );
  }
}

其他答案很好,尤其是Brandon使用Hooks的情况,但这可以使您的数据逻辑保持在容器中,并使表示组件保持简单。

答案 3 :(得分:0)

如果内心不需要了解彼此,其他答案是正确的,但是我不认为这是您的情况。如果单击第三颗心,则您可能还希望填写#1和#2。在这种情况下,应该从Heart组件中 out 取出您的状态,然后移至Test组件:< / p>

L1 = [ 9, 12, 17, 25 ]
L2 = [ 3, 5, 11, 13, 16 ]

for i in L1:
    L2.append(i)

L2.sort()

print(L2)

当您单击第三颗心时,#1,#2和#3会被“点赞”,而#4和#5不会。因此,如果您想单击#3并且仅填写第三个心,则其他解决方案也可以使用,但是如果这更像是评级系统,则应提升状态并在父级(测试)组件级别进行管理。 / p>