在React中使用array.map内部的条件逻辑



我正在学习React,并使用array.map在一组人上循环并显示他们的信息。我还需要向每个人显示一条信息(voterMessage(,根据该人的年龄而有所不同

我知道我可以用内联三元运算符来实现这一点(因为在这种情况下我只有两个选项(,但我想用if/else来实现,以防以后需要添加更多选项

我不知道如何以及在哪里设置这个条件才能使它发挥作用。我已经将条件移动到代码中的几个位置,每次都会得到不同的错误。下面的代码在第12行抛出了一个Unexpected Token错误(else语句后面的p标记(。

研究这个问题只会带来处理return语句之外的条件的方法、使用三元运算符的方法以及直接访问属性的方法,但当属性是数组并且条件必须基于数组中对象的属性应用于数组中的每个对象时,我找不到这样做的方法。

const Person = (props) => {
let voterMessage;
return (

<div>{props.people.map(p =>
{if (p.age > 18) {
voterMessage = "please go vote"
} 
else {
voterMessage = "you must be 18"
}}           
<p>Learn some information about this person</p>
<ul>
<li>Name: {p.name}</li>
<li>Age: {p.age}</li>
<h3>{voterMessage}</h3>
</ul>
)}</div>
)
}

.map是一个需要返回值的函数。它基本上是通过将已经存在的值转换为新的值,从当前的值创建一个新的数组。你最初的函数是一堆花括号,所以我把它精简了一点。我要指出的是,<ul>标记中的<h3>让我很困扰,我认为它不是有效的HTML,但我将让您来解决这个问题。

另一个问题是,您在map函数的外部声明了voterMessage变量,这可能会在以后给您带来一些错误。然而,事实上,您并不需要它

{p.age >= 18 ? 'Please go vote' : 'You must be 18'}

称为三元表达式。当处理依赖于变量的语句时,它们非常有用,并且只能输出两个选项中的一个。

如果你有任何问题,请告诉我。

const Person = (props) => {
return (
<div>
{props.people.map((p) => {
let voterMessage;
if (p.age >= 18) {
voterMessage = "Please go vote";
} else {
voterMessage = "You must be 18";
}
return (
<React.Fragment>
<p>Learn some information about this person</p>
<ul>
<li>Name: {p.name}</li>
<li>Age: {p.age}</li>
<h3>{voterMessage}</h3>
</ul>
</React.Fragment>
);
})}
</div>
);
};

编辑

OP特别希望if/else代替三元。更新了代码以反映这一点,但将三元链接保留在那里,供其他可能阅读此问题的人使用。

如果

删除此

{ if (p.age > 18) {
voterMessage = "please go vote"
}else {
voterMessage = "you must be 18"
}
}

在你的h3里面添加

{p.age > 18 ? 'please go vote' : 'you must be 18'}

如果你想有多个if else,你可以嵌套它

{p.age > 18 ? 'please go vote' 
: p.age > 17 ? 'almost there' : 'Whats taking you so long' }

这个设计似乎有点混乱。让一个名为Person的组件接受一组人作为道具是没有意义的。每个Person都应该是一个不同的组件,People的集合是映射与人员相关的数据阵列的更好位置。这将使您的错误更容易处理(根本问题是您试图将JSX放入函数块之外(。

例如:

const Person = ({person: {name, age}}) =>
<div>
<p>Learn some information about this person</p>
<ul>
<li>Name: {name}</li>
<li>Age: {age}</li>
</ul>
<h3>{age < 18 ? "you must be 18" : "please go vote"}</h3>
</div>
;
const People = ({people}) =>
<div>
{people.map(e => <Person key={e.id} person={e} />)}
</div>
;
const people = [
{
id: 1,
age: 19,
name: "tom",
},
{
id: 2,
age: 15,
name: "jerry",
}
];
ReactDOM.createRoot(document.querySelector("#app"))
.render(<People people={people} />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id="app"></div>

你提到你想在没有三元的情况下这样做。目前,这只会使代码变得冗长且更难阅读,但这里是为了进行比较。我不建议这样编码。

const Person = ({person: {name, age}}) => {
let votingMessage = "please go vote";
if (age < 18) {
votingMessage = "you must be 18";
}
return (
<div>
<p>Learn some information about this person</p> 
<ul>
<li>Name: {name}</li>
<li>Age: {age}</li> 
</ul>
<h3>{votingMessage}</h3>
</div>
);
};
const People = ({people}) => 
<div>
{people.map(e => <Person key={e.id} person={e} />)}
</div>;
const people = [
{
id: 1,
age: 19,
name: "tom",
},
{
id: 2,
age: 15,
name: "jerry",
}
];
ReactDOM.createRoot(document.querySelector("#app"))
.render(<People people={people} />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id="app"></div>

最新更新