gpt4 book ai didi

javascript - 如何在React中创建appenChild或删除按钮功能

转载 作者:行者123 更新时间:2023-11-30 14:22:25 28 4
gpt4 key购买 nike

好!我在这里列出了这个问题的更简洁示例:Need Help Creating a Simple List Maker App in React JS

我正在研究React,并为我的投资组合构建一个简单的列表制作器应用程序。但是我卡住了!我正在尝试为输入表单和按钮创建功能,当单击它们时,会将信息添加到页面正文的列表中。当我研究dom操作时,我先做了一个getElementByTagName然后是li.appendChild等。但是现在我不知道如何在React中做到这一点,因为从我的阅读中,您不应该在react中进行dom操作。谁能帮助我通过创建适当的功能来允许按钮将内容添加到列表中吗?并删除项目吗?到目前为止,这是我的代码:

import React, { Component } from 'react';
import './App.css';
import Navigation from './components/Navigation';
import ListInput from './components/ListInput';
import ListName from './components/ListName';

class App extends Component {
constructor() {
super();
this.state = {
input: '',
items: []
};
}

addItem = () => {
this.setState(state => {
let inputValue = this.input.current.value;
if (inputValue !== '') {
this.setState({
items: [this.state.items, inputValue]
})
}
})
}


onButtonEnter = () => {
this.addItem();
}

render() {
return (
<div className="App">
<Navigation />
<ListName />
<ListInput addItem={this.addItem}
onButtonEnter={this.onButtonEnter} />
</div>
);
}
}

export default App;


这是我的ListInput组件的代码,我在其中构建输入表单和将列表信息提交到页面主体的按钮:

import React from "react";
import "./ListInput.css";

const ListInput = ({ addItem, onButtonEnter }) => {
return (
<div>
<p className="center f2">{"Enter List Item"}</p>
<div className="center">
<div className="center f3 br-6 shadow-5 pa3 ">
<input
type="text"
className="f4 pa2 w-70 center"
placeholder="Enter Here"
/>
<button
className="w-30 grow f4 link ph3 pv2 dib white bg-black"
onClick={onButtonEnter}
onSubmit={addItem}
>
{"Enter"}
</button>
</div>
</div>
</div>
);
};

export default ListInput;


我尝试在我的一个功能中使用.push,但是它没有用,而且我还是真的不明白。任何帮助将不胜感激,谢谢!

最佳答案

react中,我们使用声明性方式编写代码。


我们得到一个state来保存我们的数据并充当我们的真理之源
我们获得了返回可视化效果的组件和功能
根据当前的state


因此,如果您有Items的列表并要显示它们,则将在该列表上循环并为每个项目返回Item的直观表示。

当您要添加或删除项目时,只需在该状态下从该列表添加或删除项目。

这是这种用法的一个运行示例:



class Item extends React.Component {
remove = () => {
const { id, onRemove } = this.props;
onRemove(id);
};

render() {
const { text } = this.props;
return (
<div style={{ display: "flex" }}>
<button onClick={this.remove}>Remove</button>
<div>{text}</div>
</div>
);
}
}

class App extends React.Component {
state = {
items: [
{ id: 1, text: "item 1" },
{ id: 2, text: "item 2" },
{ id: 3, text: "item 3" }
]
};

addItem = () => {
this.setState(state => {
const { items } = state;
const newId = uuid();
const newItem = { id: newId, text: `item ${newId}` };
return {
items: [...items, newItem]
};
});
};

onItemRemove = itemId => {
this.setState(state => {
const { items } = state;
const filteredItems = items.filter(item => item.id !== itemId);
return {
items: filteredItems
};
});
};

render() {
const { items } = this.state;
return (
<div>
<div>
<button onClick={this.addItem}>Add Item</button>
<hr />
</div>
{items.map(item => (
<Item
key={item.id}
id={item.id}
text={item.text}
onRemove={this.onItemRemove}
/>
))}
</div>
);
}
}

const root = document.getElementById("root");
ReactDOM.render(<App />, 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>
<script src="https://cdnjs.cloudflare.com/ajax/libs/node-uuid/1.4.8/uuid.js"></script>
<div id="root"/>





编辑
得知您仍然感到困惑,我们感到遗憾,但这没关系!您正在学习一种新技术,而起点总是最艰难的:)

我建议您仔细阅读以 "Thinking in React"开头的DOCS,并逐步进行操作。

在您最初的问题中,您问过如何“添加”或删除反应中的孩子,我认为我的回答涵盖了这一点。
至于你的新问题


  我最大的问题是我不了解您和其他人如何弄清楚该怎么做...


只要您不断写作和体验,您就会随着时间的流逝而得到它。
我不确定我是否完全理解在我的示例或您看到的任何其他示例中引起您困惑的原因。



据我所知,我将尽力打破您的目标:


您要呈现项目列表。
您需要一个 Form来让用户输入文本并添加一个新的
该文本的项目。
您希望用户能够删除项目。


现在让我们来讨论关注点分离,以设计该应用程序。

从最小的部分开始, Item

项目
如果要显示项目列表,则可能需要 <Item />组件。
它的工作是什么?让我们说现在渲染一些文本。
因此,该项目需要一个 text道具,它看起来像这样:

const Item = ({text}) => <div>{text}</div>


好,上移。
物品清单
如果要显示多个项目,则需要获取一个项目数组并在它们上循环以呈现它们。
这是 react中的常见任务,我们大多使用 Array.prototype.map来完成。所以我们的组件看起来像这样:

const ItemList = ({ items }) => (
<div>
{
items.map(item => <Item key={item.id} text={item.text} />)
}
</div>
)


注意 key prop

现在可以,但是以下哪个组件应该负责添加和删除密钥?没有!这些组件负责外观。
我们需要另一个组件来管理数据和逻辑,甚至可能根本不在乎事物的外观。

ItemListContainer
该组件需要处理添加和删除项目的逻辑,甚至可能使项目保持其状态,因此可以将其提供给 ItemList
如果需要状态,则应为 React.Component类:

class ItemListContainer extends React.Component {
state = {
// starting with 2 items
items: [{ id: 1, text: "item 1" }, { id: 2, text: "item 2" }]
};

render() {
const { items } = this.state;
return <ItemList items={items} />;
}
}


此时,我们有一个可以显示项目的工作应用程序:



const Item = ({ text }) => <div>{text}</div>;

const ItemList = ({ items }) => (
<div>{items.map(item => <Item key={item.id} text={item.text} />)}</div>
);

class ItemListContainer extends React.Component {
state = {
// starting with 2 items
items: [{ id: 1, text: "item 1" }, { id: 2, text: "item 2" }]
};

render() {
const { items } = this.state;
return <ItemList items={items} />;
}
}

const rootElement = document.getElementById("root");
ReactDOM.render(<ItemListContainer />, rootElement);

<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" />





现在,让我们考虑一下我们需要添加什么?


addItem函数。
项目文本的 input
提交 button以触发 addItem功能。


好的,因此我们需要另一个组件来包装 input,并且 button可以将其称为 ItemForm

但是让我们问问自己, ItemForm是否需要处理添加项的逻辑? (提示不!)。

保存数据并负责我们的逻辑的组件是 ItemListContainer。这是我们编写 addItem函数的地方。
但是,我们还需要从 ItemForm中获取输入文本,并且仅在单击提交 button时才需要。

我认为我们也需要一个 ItemForm的状态。它将管理输入的更改文本,并在提交时触发传递给它的回调。
它看起来像这样:

class ItemForm extends React.Component {
state = { value: "" };

onValueChange = ({ target }) => this.setState({ value: target.value });

onSubmit = () => {
const { onSubmit } = this.props;
const { value } = this.state;

// just validating empty strings
if (!value) return;

// clearing the input field
this.setState({ value: "" });

// passing the value to the callback from props
onSubmit(value);
};

render() {
const { value } = this.state;
return (
<div>
<input
placeholder="enter item text"
type="text"
value={value}
onChange={this.onValueChange}
/>
<button onClick={this.onSubmit}>Submit</button>
</div>
);
}
}


大!现在我们要做的就是在 ItemForm中渲染 ItemListContainer
我们将创建一个虚拟的 addItem函数以记录该值以查看其工作原理:

class ItemListContainer extends React.Component {
state = {
// starting with 2 items
items: [{ id: 1, text: "item 1" }, { id: 2, text: "item 2" }]
};

addItem = value => {
console.log(value);
}

render() {
const { items } = this.state;
return (
<div>
<ItemForm onSubmit={this.addItem} />
<ItemList items={items} />
</div>
);
}
}


这就是整个应用程序正在运行:



const Item = ({ text }) => <div>{text}</div>;

const ItemList = ({ items }) => (
<div>{items.map(item => <Item key={item.id} text={item.text} />)}</div>
);

class ItemForm extends React.Component {
state = { value: "" };

onValueChange = ({ target }) => this.setState({ value: target.value });

onSubmit = () => {
const { onSubmit } = this.props;
const { value } = this.state;

// just validating empty strings
if (!value) return;

// clearing the input field
this.setState({ value: "" });

// passing the value to the callback from props
onSubmit(value);
};

render() {
const { value } = this.state;
return (
<div>
<input
placeholder="enter item text"
type="text"
value={value}
onChange={this.onValueChange}
/>
<button onClick={this.onSubmit}>Submit</button>
</div>
);
}
}

class ItemListContainer extends React.Component {
state = {
// starting with 2 items
items: [{ id: 1, text: "item 1" }, { id: 2, text: "item 2" }]
};

addItem = value => {
console.log(value);
}

render() {
const { items } = this.state;
return (
<div>
<ItemForm onSubmit={this.addItem} />
<ItemList items={items} />
</div>
);
}
}

const rootElement = document.getElementById("root");
ReactDOM.render(<ItemListContainer />, rootElement);

<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" />





OK,现在为 addItem逻辑。众所周知,项目是处于状态的数组,如果要添加新项目,我们要做的就是将其添加到数组中。
我们不会使用 this.state.push(newItem),因为这会改变数组,这在我们的反应世界中是一个很大的禁忌。
因此,我们的 addItem函数可能如下所示:

addItem = value => {
this.setState(state => {
const { items } = state;
// watch it we are missing an id property here!!!
const newItem = { text: value };
return {
items: [...items, newItem]
};
});
};


如您所见,这很简单,只需使用 item作为 value属性创建一个新的 text。但是请注意,我们没有提供 id属性,对于 key<Item />道具我们将需要它,并且稍后在我们要删除 item时将需要它(我们将基于在 id上)。
在这里,您有两种选择,我将选择 uuid

请参阅带有新逻辑的运行示例(还添加了 uuid):



const Item = ({ text }) => <div>{text}</div>;

const ItemList = ({ items }) => (
<div>{items.map(item => <Item key={item.id} text={item.text} />)}</div>
);

class ItemForm extends React.Component {
state = { value: "" };

onValueChange = ({ target }) => this.setState({ value: target.value });

onSubmit = () => {
const { onSubmit } = this.props;
const { value } = this.state;

// just validating empty strings
if (!value) return;

// clearing the input field
this.setState({ value: "" });

// passing the value to the callback from props
onSubmit(value);
};

render() {
const { value } = this.state;
return (
<div>
<input
placeholder="enter item text"
type="text"
value={value}
onChange={this.onValueChange}
/>
<button onClick={this.onSubmit}>Submit</button>
</div>
);
}
}

class ItemListContainer extends React.Component {
state = {
// starting with 2 items
items: [{ id: 1, text: "item 1" }, { id: 2, text: "item 2" }]
};

addItem = value => {
this.setState(state => {
const { items } = state;
const newId = uuid();
const newItem = { text: value, id: newId };
return {
items: [...items, newItem]
};
});
};

render() {
const { items } = this.state;
return (
<div>
<ItemForm onSubmit={this.addItem} />
<ItemList items={items} />
</div>
);
}
}

const rootElement = document.getElementById("root");
ReactDOM.render(<ItemListContainer />, rootElement);

<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>
<script src="https://cdnjs.cloudflare.com/ajax/libs/node-uuid/1.4.8/uuid.js"></script>

<div id="root" />





移除物品
这并不比添加项目难,我们只需要两件事:


在每个 button旁边删除一个 Item
removeItem函数,它将接受与之相关的ID
特定的 item


为此,我们将需要稍微更改 Item组件。

const Item = ({ text, onRemove }) => (
<div>
<button onClick={onRemove}>X</button>
{text}
</div>
);


如您所见,每个 Item现在都收到另一个道具 onRemove
我们需要将其从呈现每个 ItemList的组件 Item中传递出去:

const ItemList = ({ items, onRemove }) => (
<div>
{items.map(item => (
<Item key={item.id} text={item.text} onRemove={() => onRemove(item.id)} />
))}
</div>
);


请注意, ItemList如何也可以接收 onRemove道具,而不仅仅是传递它。它使用匿名函数将其向下传递,并传递 id作为参数。记得?我们说过,我们需要这个 id才能知道要删除哪个 item

现在,让我们使用新的 ItemListContainer函数来查看 onRemove的样子:

class ItemListContainer extends React.Component {
state = {
// starting with 2 items
items: [{ id: 1, text: "item 1" }, { id: 2, text: "item 2" }]
};

addItem = value => {
this.setState(state => {
const { items } = state;
const newId = uuid();
const newItem = { text: value, id: newId };
return {
items: [...items, newItem]
};
});
};

onRemove = id => console.log(id);

render() {
const { items } = this.state;
return (
<div>
<ItemForm onSubmit={this.addItem} />
<ItemList items={items} onRemove={this.onRemove} />
</div>
);
}
}


我们仅记录 id只是为了查看其工作情况。
这是运行代码:



const Item = ({ text, onRemove }) => (
<div>
<button onClick={onRemove}>X</button>
{text}
</div>
);

const ItemList = ({ items, onRemove }) => (
<div>
{items.map(item => (
<Item key={item.id} text={item.text} onRemove={() => onRemove(item.id)} />
))}
</div>
);

class ItemForm extends React.Component {
state = { value: "" };

onValueChange = ({ target }) => this.setState({ value: target.value });

onSubmit = () => {
const { onSubmit } = this.props;
const { value } = this.state;

// just validating empty strings
if (!value) return;

// clearing the input field
this.setState({ value: "" });

// passing the value to the callback from props
onSubmit(value);
};

render() {
const { value } = this.state;
return (
<div>
<input
placeholder="enter item text"
type="text"
value={value}
onChange={this.onValueChange}
/>
<button onClick={this.onSubmit}>Submit</button>
</div>
);
}
}

class ItemListContainer extends React.Component {
state = {
// starting with 2 items
items: [{ id: 1, text: "item 1" }, { id: 2, text: "item 2" }]
};

addItem = value => {
this.setState(state => {
const { items } = state;
const newId = uuid();
const newItem = { text: value, id: newId };
return {
items: [...items, newItem]
};
});
};

onRemove = id => console.log(id);

render() {
const { items } = this.state;
return (
<div>
<ItemForm onSubmit={this.addItem} />
<ItemList items={items} onRemove={this.onRemove} />
</div>
);
}
}

const rootElement = document.getElementById("root");
ReactDOM.render(<ItemListContainer />, rootElement);

<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>
<script src="https://cdnjs.cloudflare.com/ajax/libs/node-uuid/1.4.8/uuid.js"></script>

<div id="root" />





现在我们已经拥有了所有的东西,我们可以编写我们的逻辑了。这很简单,就像使用 Array.prototype.filter()一样:

onRemove = id => {
this.setState(state => {
const { items } = state;
const filteredItems = items.filter(item => item.id !== id);
return { items: filteredItems };
});
};


现在我们可以按预期进行所有操作,您可以在此处看到它(是!):



const Item = ({ text, onRemove }) => (
<div>
<button onClick={onRemove}>X</button>
{text}
</div>
);

const ItemList = ({ items, onRemove }) => (
<div>
{items.map(item => (
<Item key={item.id} text={item.text} onRemove={() => onRemove(item.id)} />
))}
</div>
);

class ItemForm extends React.Component {
state = { value: "" };

onValueChange = ({ target }) => this.setState({ value: target.value });

onSubmit = () => {
const { onSubmit } = this.props;
const { value } = this.state;

// just validating empty strings
if (!value) return;

// clearing the input field
this.setState({ value: "" });

// passing the value to the callback from props
onSubmit(value);
};

render() {
const { value } = this.state;
return (
<div>
<input
placeholder="enter item text"
type="text"
value={value}
onChange={this.onValueChange}
/>
<button onClick={this.onSubmit}>Submit</button>
</div>
);
}
}

class ItemListContainer extends React.Component {
state = {
// starting with 2 items
items: [{ id: 1, text: "item 1" }, { id: 2, text: "item 2" }]
};

addItem = value => {
this.setState(state => {
const { items } = state;
const newId = uuid();
const newItem = { text: value, id: newId };
return {
items: [...items, newItem]
};
});
};

onRemove = id => {
this.setState(state => {
const { items } = state;
const filteredItems = items.filter(item => item.id !== id);
return { items: filteredItems };
});
};

render() {
const { items } = this.state;
return (
<div>
<ItemForm onSubmit={this.addItem} />
<ItemList items={items} onRemove={this.onRemove} />
</div>
);
}
}

const rootElement = document.getElementById("root");
ReactDOM.render(<ItemListContainer />, rootElement);

<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>
<script src="https://cdnjs.cloudflare.com/ajax/libs/node-uuid/1.4.8/uuid.js"></script>

<div id="root"/>







请注意,在我的示例中有一些最佳实践,例如内联匿名函数。但现在不用担心,专注于基础知识

我希望这可以消除您的困惑,并为您学习这项出色的技术提供一个良好的起点。 :)

关于javascript - 如何在React中创建appenChild或删除按钮功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52523264/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com