React - JSX 语法问题,以及如何使用地图进行迭代并在换行符上显示项目
本文介绍了React - JSX 语法问题,以及如何使用地图进行迭代并在换行符上显示项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!
问题描述
我是 React 菜鸟,正在制作一个 ToDo 列表样式Recipe List app.我有一个功能组件 Item.js,我正在使用 JSX 和 map 函数来遍历每个配方项并显示它们.我希望每个食谱项都出现在新行上,但是当我使用 .map 遍历它们时,React 会将整个食谱项列表放入一个 p 标签,而不是每个项目的一个 p 标签.
如何遍历配方项并将它们显示在不同的行上?即使我尝试将它们显示为无序列表,React 也希望将每个项目放入一个 li 标签中.
这是我的代码:
从'react'导入反应;从'react-bootstrap/lib/Button'导入按钮;const Item = (props) =>(<div className="配方-项目-容器";键={props.text}>{props.items.map((item, index) =><div className=配方-项目";键={索引}><h3>{项目}</h3><p>{props.ingredients[index]}</p><div className="buttons-container"><Button className="编辑按钮";onClick={() =>props.edit(item, index)}>编辑</按钮>
同样在 {props.items.map((item, index) => 行,如果我在 => 之后添加一个花括号,我得到一个错误.我有一个 React/安装了 JSX linter,但它没有捕获任何东西.这是什么问题?
我知道这可能是一个菜鸟错误,但 JSX 在这里让我陷入了循环.
解决方案
这是工作版本.
class App extends React.Component {状态 = {项目:[南瓜派"、意大利面"、洋葱派"]、配料: [[南瓜泥"、甜炼乳"、鸡蛋"、南瓜派香料"、派皮"]、[面条"、番茄"、酱汁"、肉丸"]、[洋葱",馅饼皮"],],}使成为() {返回 (<div className="box"><Item items={this.state.items} 成分={this.state.ingredients}/></div>);}}常量项目 = 道具 =>(<div className="Recipe-Item-Container" key={props.text}>{props.items.map( ( 项目, 索引 ) => (<div className="Recipe-Item" key={item}><h3>{项目}</h3><ul>{props.ingredients[索引].map(成分=><li key={ingredient}>{ingredient}</li>)}</ul><div className="按钮容器"><button className="edit-button" onClick={() =>props.edit(item, index)}>编辑</按钮><button className="delete-button" onClick={() =>props.delete(item, index)}>删除</按钮></div></div>) )}</div></div>);ReactDOM.render(<App/>, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></脚本><script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script><div id="root"></div>
但如果我是你,我会改变我的状态.类似的东西:
class App extends React.Component {状态 = {项目: [{名称:南瓜派",配料: [南瓜泥",甜炼乳",蛋",南瓜派香料",馅饼皮"]},{名称:意大利面",食材:[面条"、番茄"、酱汁"、肉丸"]},{名称:洋葱派",原料:[洋葱"、派皮"]}]};removeItem = 项目 =>{const newItems = this.state.items.filter(el => el.name !== item.name);this.setState({ items: newItems });};编辑项目 = 项目 =>alert(`${item.name} 将被编辑`);渲染项 = () =>this.state.items.map(item => (<项目键={item.name}项目={项目}removeItem={this.removeItem}editItem={this.editItem}/>));使成为() {return <div className="box">{this.renderItems()}</div>;}}常量项目 = 道具 =>{const { item, removeItem, editItem } = props;常量句柄移除 = () =>删除项目(项目);常量句柄编辑 = () =>编辑项目(项目);返回 (<div className="Recipe-Item-Container" key={props.text}><div className="Recipe-Item"><h3>{item.name}</h3><ul>{item.ingredients.map(ingredient => (<li key={ingredient}>{ingredient}</li>))}</ul><div className="按钮容器"><button className="edit-button" onClick={handleEdit}>编辑</按钮><button className="delete-button" onClick={handleRemove}>删除</按钮></div></div></div></div>);};ReactDOM.render(<App/>, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></脚本><script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script><div id="root"></div>
变化
状态形状:我们不是保存两个数组,而是为每个项目保存一个对象.该对象具有 name 和 ingredients 属性.也许在未来,它可能有一个唯一的id?对象很灵活. 我们不是将所有项目都传递给 Item 组件,而是将项目映射到父组件中,然后仅将一项传递给 Item 组件. 我们仍然在父级中定义了处理函数.但是,我们并没有直接在按钮的回调函数中使用它们和箭头函数.因此,它们不会在每次渲染中重新创建.此外,我们不必使用索引将项目传递回父项.我们有 item 道具本身!您可以看到我们如何处理删除功能:使用 .filter 您可以将相同的功能应用于其他功能..map、.filter、Object.assign 或扩展语法都是很好的工具.只是,避免直接改变你的状态. I'm a React noob and making a ToDo list style Recipe List app. I have a functional component, Item.js, and I am using JSX and the map function to iterate through each recipe item and display them. I want each recipe item to appear on a new line, but when I use .map to iterate through them React puts the entire list of recipe items into one p tag instead of one p tag for each item.
How can I iterate through the recipe items and display them on separate lines? Even if I try to display them as an unordered list React wants to throw each item in one li tag.
Here is my code:
import React from 'react';
import Button from 'react-bootstrap/lib/Button';
const Item = (props) => (
<div>
<div className="Recipe-Item-Container" key={props.text}>
{props.items.map((item, index) =>
<div className="Recipe-Item" key={index}>
<h3>{item}</h3>
<p>{props.ingredients[index]}</p>
<div className="buttons-container">
<Button className="edit-button" onClick={() => props.edit(item, index)}>Edit</Button>
<Button className="delete-button" onClick={() => props.delete(item, index)}>Delete</Button>
</div>
</div>
)}
</div>
</div>
)
export default Item;
Also on the {props.items.map((item, index) => line if I add a curly brace after the => I get an error. I have a React/JSX linter installed and it isn't catching anything. What's the issue?
I know this is probably a noob error but JSX is throwing me for a loop here.
解决方案
Here is the working version.
class App extends React.Component {
state = {
items: [ "Pumpkin Pie", "Spaghetti", "Onion Pie" ],
ingredients: [
[ "Pumpkin Puree", "Sweetened Condensed Milk", "Eggs", "Pumpkin Pie Spice", "Pie Crust" ],
[ "Noodles", "Tomatoe", "Sauce", "Meatballs" ],
[ "Onion", "Pie Crust" ],
],
}
render() {
return (
<div className="box">
<Item items={this.state.items} ingredients={this.state.ingredients} />
</div>
);
}
}
const Item = props => (
<div>
<div className="Recipe-Item-Container" key={props.text}>
{props.items.map( ( item, index ) => (
<div className="Recipe-Item" key={item}>
<h3>{item}</h3>
<ul>
{
props.ingredients[ index ].map( ingredient =>
<li key={ingredient}>{ingredient}</li> )
}
</ul>
<div className="buttons-container">
<button className="edit-button" onClick={() => props.edit( item, index )}>Edit</button>
<button className="delete-button" onClick={() => props.delete( item, index )}>Delete</button>
</div>
</div>
) )}
</div>
</div>
);
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
But if I were you I would change my state shape. Something like that:
class App extends React.Component {
state = {
items: [
{
name: "Pumpkin Pie",
ingredients: [
"Pumpkin Puree",
"Sweetened Condensed Milk",
"Eggs",
"Pumpkin Pie Spice",
"Pie Crust"
]
},
{
name: "Spaghetti",
ingredients: ["Noodles", "Tomatoe", "Sauce", "Meatballs"]
},
{
name: "Onion Pie",
ingredients: ["Onion", "Pie Crust"]
}
]
};
removeItem = item => {
const newItems = this.state.items.filter(el => el.name !== item.name);
this.setState({ items: newItems });
};
editItem = item => alert(`${item.name} will be edited`);
renderItems = () =>
this.state.items.map(item => (
<Item
key={item.name}
item={item}
removeItem={this.removeItem}
editItem={this.editItem}
/>
));
render() {
return <div className="box">{this.renderItems()}</div>;
}
}
const Item = props => {
const { item, removeItem, editItem } = props;
const handleRemove = () => removeItem(item);
const handleEdit = () => editItem(item);
return (
<div>
<div className="Recipe-Item-Container" key={props.text}>
<div className="Recipe-Item">
<h3>{item.name}</h3>
<ul>
{item.ingredients.map(ingredient => (
<li key={ingredient}>{ingredient}</li>
))}
</ul>
<div className="buttons-container">
<button className="edit-button" onClick={handleEdit}>
Edit
</button>
<button className="delete-button" onClick={handleRemove}>
Delete
</button>
</div>
</div>
</div>
</div>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
Changes
State shape: Instead of holding two arrays, we are keeping an object per item. This object has a name and ingredients property. Maybe in the future, it may have a unique id? Objects are flexible.
Instead of passing all the items to an Item component, we are mapping the items in the parent component and pass just one item to the Item component.
We still have handler functions defined in the parent. But, we are not using them directly in the button's callback with an arrow function. So, they are not recreated in every render. Also, we don't have to use an index to pass the items back to the parent. We have the item prop itself! You can see how we handle the remove functionality: with .filter You can apply the same functionality to other functions. .map, .filter, Object.assign or spread syntax are all good tools. Just, avoid mutating your state directly.
这篇关于React - JSX 语法问题,以及如何使用地图进行迭代并在换行符上显示项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!
相关推荐
首先,我们需要在百度地图开放平台上申请一个开发者账号,并创建一个应用。在创建应用的过程中,我们会得到一个密钥(ak),这是调用API的凭证。 接下来,我们需要准备一个PHP文件,以便可以在网页中调用。首先,我们需要引入百度地图API的JS文件,代码如下...
ajax请求获取json数据并处理的实例代码 $.ajax({ type: 'GET', url: 'https://localhost:44369/UserInfo/EditUserJson',//请求数据 data: json,//传递数据 //dataType:'json/text',//预计服务器返回的类型 timeout: 3000,//请求超时的时间 //回调函数传参 suc...
在JavaScript中,我们有多种方法可以删除数组中的指定元素。以下给出了5种常见的方法并提供了相应的代码示例: 1.使用splice()方法: let array = [0, 1, 2, 3, 4, 5];let index = array.indexOf(2);if (index -1) { array.splice(index, 1);}// array = [0,...
1. 如果是ajax嵌套了 页面, 请确保 只有最外层的页面引入了layui.css 和 layui.js ,内层页面 切记不要再次引入 2. 具体代码如下 layui.use(['form', 'upload'], function(){ var form = layui.form; form.render(); // 加入这一句});...
在layui树状组件tree中,勾选问题可以通过以下方法解决: 通过tree的oncheck事件来监听勾选操作,然后根据勾选状态进行相应的处理。例如: tree.on('check', function(obj) { // 获取勾选状态 var isChecked = obj.checked; // 获取当前节点数据 var data =...
经常用到layui的朋友都知道,layui tree默认是不能自定义图标的,那么我们要自定义的话要怎么操作呢? 首先用编辑器软件(修改时候用编辑器记得编码),打开layui.js。搜索: i class="layui-icon layui-icon-file" 改为如下代码: i class="'+ (i.icon || "l...