在 ReactJs 中创建一个标签输入组件。
项目设置
我们将使用 ReactJs 构建组件。首先,让我们安装一些必要的组件。我们将使用 React 的CRA创建一个 React 应用,或者您也可以使用任何入门套件。接下来,让我们设置React应用。
npx create-react-app tags-input
cd tags-input
我们开始吧!
在这个index.js文件中,我们将编写基础组件的代码App,你可以随意命名它。
// index.js
import React from "react";
import ReactDOM from "react-dom";
import "./styles.scss";
const App = () => {
return (
<div className="App">
<span>Hello World!</span>
</div>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
标签输入组件
我们将使用函数式组件和 React 的useStatehook 来实现有状态化。
// TagsInput.jsx
import React from "react";
const TagsInput = () => {
const [tags, setTags] = React.useState([]);
return (
<div className="tags-input">
<ul>
{tags.map((tag, index) => (
<li key={index}>
<span>{tag}</span>
<i className="material-icons">close</i>
</li>
))}
</ul>
<input
type="text"
placeholder="Press enter to add tags"
/>
</div>
);
};
export default TagsInput;
由于我们要在状态中存储一个标签数组,所以我们可以将其初始化为空数组。hookuseState返回两个值,即当前状态和一个可用于更新状态的函数。我们使用数组解构来获取这两个值useState。在本例中,当前状态称为 `state` tags,用于更新状态的函数称为 `update` setTags。
然后,在返回函数中,我们对tags数组进行映射,并显示用户将在该状态中添加的所有标签。
添加标签功能
让我们来创建添加标签的功能。我们将为标签添加一个事件处理程序onKeyUp,input并返回一个名为 `addtags` 的函数,并将 `tags`作为参数addTags()传递给它。event
// TagsInput.jsx
...
<input
type="text"
onKeyUp={event => addTags(event)}
placeholder="Press enter to add tags"
/>
...
接下来,我们将在组件中定义addTags()上面的函数。return
// TagsInput.jsx
import React from "react";
const TagsInput = () => {
const [tags, setTags] = React.useState([]);
const addTags = event => {
if (event.key === "Enter" && event.target.value !== "") {
setTags([...tags, event.target.value]);
event.target.value = "";
}
};
return (
...
);
};
我们可以使用键码来确保只有在用户按下Enter按键后,标签才会被添加到状态中。除此之外,我们还添加了一个条件,以防止将空标签添加到状态中。
然后,在我们的if条件成立的情况下,如果条件为真,我们可以使用函数添加用户输入的标签setTags()。你会注意到我在这里使用了扩展运算符(`\n` ...tags),首先添加已有的标签,然后再添加用户刚刚输入的标签。这种语法确保新输入的标签添加到标签数组的末尾,最后清空输入标签的值,以便用户可以输入新的标签。
移除标签功能
要移除标签,用户可以点击所有标签旁边的关闭图标。我传递了一个onClick事件处理程序来处理移除标签的功能。
// TagsInput.jsx
...
{tags.map((tag, index) => (
<li key={index}>
<span>{tag}</span>
<i
className="material-icons"
onClick={() => removeTags(index)}
>
close
</i>
</li>
))}
...
removeTags()当用户点击关闭图标时,我们会返回一个值,并将index被点击要移除的标签的值传递给该值。现在,就在我们的下方addTags(),我们将添加removeTags()。
// TagsInput.jsx
...
const addTags = event => {
...
};
const removeTags = index => {
setTags([...tags.filter(tag => tags.indexOf(tag) !== index)]);
};
...
由于我们传递的是index用户想要移除的标签的索引,因此我们可以使用filter()方法根据标签的索引来移除它。在上面代码的第 8 行,我们遍历标签数组,查找索引与用户想要移除的标签索引匹配的标签。一旦找到,该标签将被过滤掉,其余标签将保留在结果数组中。最后,我们再次使用扩展运算符将结果标签数组传递进去,然后使用setTags()该方法更新状态。
让我们将 TagsInput 组件导入到我们的基础组件中。
// index.js
import React from "react";
import ReactDOM from "react-dom";
import "./styles.scss";
import TagsInput from './TagsInput';
const App = () => {
return (
<div className="App">
<TagsInput />
</div>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
现在,我们如何获取用户添加到基础组件中的标签呢?我们将selectedTags在基础组件中声明一个函数,并将其作为 props 传递给我们的TagsInput组件。
...
const App = () => {
const selectedTags = tags => console.log(tags)};
return (
<div className="App">
<TagsInput selectedTags={selectedTags}/>
</div>
);
};
...
TagsInput现在,我们可以从组件中调用该selectedTags方法,并将标签数组传递给基础组件。
// TagsInput.jsx
...
const TagsInput = props => {
const [tags, setTags] = React.useState([]);
const addTags = event => {
if (event.key === "Enter" && event.target.value !== "") {
setTags([...tags, event.target.value]);
props.selectedTags([...tags, event.target.value]);
event.target.value = "";
}
};
...
};
你会注意到我们已将props作为参数传递给了TagsInput组件。我们将使用它来访问selectedTags()从基组件传递过来的。在上面代码的第 9 行,我们调用了该selectedTags()方法并传递了与setTags第 8 行相同的参数。请注意,我没有传递tags我们解构的元素本身,useState以避免传递旧的标签数组。
现在,每当用户添加新标签时,基础组件都可以访问并更新标签数组。
Codepen 演示
感谢阅读,这是我的第一篇博客文章——欢迎任何反馈!(https://www.prvnbist.com/blog/create-a-tags-input-component-in-react)!
