显示投票次数最多的数组。

3

我正在参加FullStackOpenReact入门课程,卡在1.14轶事练习中,要求应用程序显示投票最多的轶事。 浏览器能够呈现Mostvote数组,它呈现了最高投票的轶事的得票数,但无论我怎么做,都无法显示最高投票(bestAnecdote)的轶事。是否有人知道我错在哪里?先谢谢了 :)

以下是我的React代码:

import React, { useState } from 'react'

const Header = (props) => {
  return <h1>{props.contents}</h1>
}

const Button = (props) => (
  <button onClick={props.handleClick}>
    {props.text}
  </button>
) 

const Vote = ({vote}) => (
<p>has {vote} votes</p>
)

const App = () => {

  const contents = {
      text1: "Anecdote of the day",
      text2: "Anecdote with most votes"
  }

  const anecdotes = [
    'If it hurts, do it more often',
    'Adding manpower to a late software project makes it later!',
    'The first 90 percent of the code accounts for the first 10 percent of the development time...The remaining 10 percent of the code accounts for the other 90 percent of the development time.',
    'Any fool can write code that a computer can understand. Good programmers write code that humans can understand.',
    'Premature optimization is the root of all evil.',
    'Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.',
    'Programming without an extremely heavy use of console.log is same as if a doctor would refuse to use x-rays or blood tests when diagnosing patients'
  ]

  const random = () => (
    Math.floor(Math.random() * 7)
  )

  const [selected, setSelected] = useState(0)
  const [vote, setVote] = useState(new Array(anecdotes.length).fill(0))

  const Anecdotevoting = () => {
    const copy = [...vote];
      copy[selected] += 1;
      setVote(copy);
  }
  
  const Mostvote = () => (
    <p>has {Math.max(...vote)} votes</p>
  )

  const bestAnecdote = anecdotes[vote.indexOf(Mostvote)];
  
  console.log(bestAnecdote)
  return (
    <div>
      <Header contents = {contents.text1}/>
      {anecdotes[selected]}<br/>
      <Vote vote = {vote[selected]}></Vote>
      <Button handleClick={Anecdotevoting} text = 'vote'/>
      <Button handleClick={() => setSelected(random)} text = 'next anecdote'/>
      <Header contents = {contents.text2}/>
      <bestAnecdote anecdotes = {anecdotes[vote.indexOf(Mostvote)]}/>
      <Mostvote vote = {Mostvote}/>
    </div>
  )
}

export default App

1
你的问题出在 vote.indexOf(Mostvote) 这一行代码上:在这段代码中,Mostvote 是一个函数,而你试图在 vote 数组中查找该函数的索引,但是由于 vote 是一个数字数组,所以它无法找到。由于 indexOfvote 数组中找不到 Mostvote 函数,因此你会得到一个 -1 的索引值。相反,你需要查找 vote 数组中最大数字的索引。此外,你还有其他问题,试图将 bestAnecdote 作为组件使用:<bestAnecdote anecdotes ={...} />,但是 bestAnecdote 不是一个组件,它是来自你的轶事数组的字符串(或 undefined)。 - Nick Parsons
非常感谢您的建议,Nick!确实非常有帮助 :) - Lynn
2个回答

1

Nick已经提到了大部分问题。这是一个可用的版本,您可以使用它来查看问题所在:

import React, { useState } from 'react'

const Header = (props) => {
  return <h1>{props.contents}</h1>
}

const Button = (props) => (
  <button onClick={props.handleClick}>
    {props.text}
  </button>
) 

const Vote = ({vote}) => (
<p>has {vote} votes</p>
)

const BestAnecdote = (props) => {
  return <h4>{props.anecdotes}</h4>
}

const App = () => {

  const contents = {
      text1: "Anecdote of the day",
      text2: "Anecdote with most votes"
  }

  const anecdotes = [
    'If it hurts, do it more often',
    'Adding manpower to a late software project makes it later!',
    'The first 90 percent of the code accounts for the first 10 percent of the development time...The remaining 10 percent of the code accounts for the other 90 percent of the development time.',
    'Any fool can write code that a computer can understand. Good programmers write code that humans can understand.',
    'Premature optimization is the root of all evil.',
    'Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.',
    'Programming without an extremely heavy use of console.log is same as if a doctor would refuse to use x-rays or blood tests when diagnosing patients'
  ]

  const random = () => (
    Math.floor(Math.random() * 7)
  )

  const [selected, setSelected] = useState(0)
  const [vote, setVote] = useState(new Array(anecdotes.length).fill(0))

  const Anecdotevoting = () => {
    const copy = [...vote];
      copy[selected] += 1;
      setVote(copy);
  }
  
  const Mostvote = () => (
    <p>has {Math.max(...vote)} votes</p>
  )
  
  return (
    <div>
      <Header contents = {contents.text1}/>
      {anecdotes[selected]}<br/>
      <Vote vote = {vote[selected]}></Vote>
      <Button handleClick={Anecdotevoting} text = 'vote'/>
      <Button handleClick={() => setSelected(random)} text = 'next anecdote'/>
      <Header contents = {contents.text2}/>
      <BestAnecdote anecdotes = {anecdotes[vote.indexOf(Math.max(...vote))]}/>
      <Mostvote vote = {Mostvote}/>
    </div>
  )
}

export default App

非常感谢你的建议,Joseph,它起作用了! - Lynn

1

问题

  1. 您正在使用 copy[selected] += 1; 更改 Anecdotevoting 中的状态。即使您浅复制了 vote 状态,元素仍然会引用回原始元素。
  2. MostVote 值是JSX,因此 anecdotes[vote.indexOf(Mostvote)]; 总是为 -1

解决方案

更新 anecdoteVoting 处理程序以不改变状态。您可以将先前的状态映射到下一个状态,并在映射的索引匹配所选时返回新值,否则返回当前值。

const anecdoteVoting = () => {
  setVote((votes) => votes.map((vote, i) => vote + (i === selected ? 1 : 0)));
};

计算一个mostVotes和索引同时进行。
const { mostVotes, index } = vote.reduce(
  (mostVotes, curr, index) => {
    if (curr > mostVotes.mostVotes) {
      return { mostVotes: curr, index };
    }
    return mostVotes;
  },
  { mostVotes: Number.NEGATIVE_INFINITY, index: -1 }
);

...

<BestAnecdote anecdote={anecdotes[index]} />
<Vote vote={mostVotes} />

Edit display-an-array-with-the-largest-number-of-votes

完整代码:

import React, { useState } from "react";

const Header = (props) => {
  return <h1>{props.contents}</h1>;
};

const Button = (props) => (
  <button onClick={props.handleClick}>{props.text}</button>
);

const Vote = ({ vote }) => <p>has {vote} votes</p>;

const BestAnecdote = ({ anecdote }) => <p>{anecdote}</p>;

const contents = {
  text1: "Anecdote of the day",
  text2: "Anecdote with most votes"
};

const anecdotes = [
  "If it hurts, do it more often",
  "Adding manpower to a late software project makes it later!",
  "The first 90 percent of the code accounts for the first 10 percent of the development time...The remaining 10 percent of the code accounts for the other 90 percent of the development time.",
  "Any fool can write code that a computer can understand. Good programmers write code that humans can understand.",
  "Premature optimization is the root of all evil.",
  "Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.",
  "Programming without an extremely heavy use of console.log is same as if a doctor would refuse to use x-rays or blood tests when diagnosing patients"
];

const random = () => Math.floor(Math.random() * anecdotes.length);

const App = () => {
  const [selected, setSelected] = useState(0);
  const [vote, setVote] = useState(new Array(anecdotes.length).fill(0));

  const anecdoteVoting = () => {
    setVote((votes) => votes.map((vote, i) => vote + (i === selected ? 1 : 0)));
  };

  const { mostVotes, index } = vote.reduce(
    (mostVotes, curr, index) => {
      if (curr > mostVotes.mostVotes) {
        return { mostVotes: curr, index };
      }
      return mostVotes;
    },
    { mostVotes: Number.NEGATIVE_INFINITY, index: -1 }
  );

  return (
    <div>
      <Header contents={contents.text1} />
      {anecdotes[selected]}
      <br />
      <Vote vote={vote[selected]}></Vote>
      <Button handleClick={anecdoteVoting} text="vote" />
      <Button handleClick={() => setSelected(random)} text="next anecdote" />
      <Header contents={contents.text2} />
      <BestAnecdote anecdote={anecdotes[index]} />
      <Vote vote={mostVotes} />
    </div>
  );
};

1
感谢您指出问题和可能的解决方案!它们确实非常有帮助!我还发现浏览器无法呈现BestAnecdote数组,因为第一个字母以前是小写!成功修复了Bestvote如下: const BestAnecdote = () => (

{anecdotes[vote.indexOf(Math.max(...vote))]}

) return ( <> ) } ```
- Lynn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接