当我有多个子组件时,如何将值从子组件传递给父组件?

时间:2019-10-31 22:16:29

标签: javascript reactjs react-hooks

我创建了多个组件,它们具有相同的层次结构,并且在它们内部我也调用了其他组件调用,现在我想在其上创建函数,这些函数将更新作为道具传递给我的值。我设法将功能作为道具传递,但无法设法将子项的值作为参数传递给函数,因此我只能更新特定于该子项的道具。

应用


function App() {
  // eslint-disable-next-line
  const [content, setContent] = useState(images)
  const [count, setCount] = useState(content.votes)

  console.log(count)

  const upVote = (id) => {
    alert('up =>', id)
  }

  const downVote = () => {
    alert('down')
  }

  return (
    <div className="App">
      <div className="grid">
        {content.map((picture, index) => {
          return <Card key={index} picture={picture} teste={[upVote, downVote]}/>
          })
        }
      </div>
    </div>
  )
}

function Card({ picture, teste }) {

  return (
    <div className="card">
      <div className="container">
        <img
          width="300"
          alt={`id: ${picture.id}`}
          src={picture.src}
          className="image"
        />
        <Options votes={0} originalPost={picture.original_post} teste={teste[0]}/>
      </div>
    </div>
  )
}

选项

function Options({ votes, originalPost, teste }) {

  const [count, setCount] = useState(votes)
  const [styling, setStyling] = useState('#696969')

  function countStyle(count) {
    if (count > 0){
      setStyling('#008000')
    } else if (count < 0) {
      setStyling('#B22222')
    } else {
      setStyling('#696969')
    }
  }

  return (
    <div>
      <button onClick={() => teste(count)} className="buttons">teste</button>        
      <button title="Down vote" onClick={() => { 
        setCount(count - 1)
        countStyle(count-1)
        // style(count - 1)
      }} className="buttons">-</button>

      <span title="Vote counter" style={{color: styling}} className="counter">{count}</span>

      <button title="Up vote" onClick={() => {
        setCount(count + 1)
        // style(count + 1)
        countStyle(count +1)
      }} className="buttons">+</button><br></br>

      <a href={originalPost} 
        target="_blank"
        title="Click to check the original post"
        rel="noopener noreferrer"
        className="link">Original post</a>
    </div>
  )
}

1 个答案:

答案 0 :(得分:1)

我将从将您的状态整合到App组件开始。将投票保存在每个图片对象的内容数组上。将upvote和downvote函数传递给每个孩子,然后通过单击按钮调用它们。我还将根据道具而不是使用状态来计算样式。

应用

<!DOCTYPE html>
<html>
  <head>
    <title>Parcel Sandbox</title>
    <meta charset="UTF-8" />
  </head>
  <body>
    <div id="app">
      <div id="data"></div>
    </div>
    <script src="src/index.js"></script>
  </body>
</html>

function App() {
  let initialstate = images.map(image => {
    image.votes = 0;
    return image;
  });

  const [content, setContent] = useState(initialstate);

  const upVote = index => {
    setContent(content[index].votes + 1);
  };

  const downVote = index => {
    setContent(content[index].votes - 1);
  };

  return (
    <div className="App">
      <div className="grid">
        {content.map((picture, index) => {
          return <Card key={index} picture={picture} index={index} upVote={upVote} downVote={downVote} />;
        })}
      </div>
    </div>
  );
}

选项

function Card({ index, picture, ...props }) {
  const upVote = () => props.upVote(index);
  const downVote = () => props.downVote(index);

  return (
    <div className="card">
      <div className="container">
        <img
          width="300"
          alt={`id: ${picture.id}`}
          src={picture.src}
          className="image"
        />
        <Options votes={picture.votes} originalPost={picture.original_post} upVote={upVote} downVote={downVote}/>
      </div>
    </div>
  )