React 和 PropTypes
React and PropTypes
前段时间我尝试在 React 中迈出第一步。现在我正在尝试创建简单的待办事项列表应用程序。我的一位同事告诉我,将 PropTypes 与 shape 和 arrayOf 一起使用会很好。我有一个组件将数据传递给另一个组件,这是我的问题(List.js 和 ListItem.js)。我不确定何时、何地以及如何将 propTypes 与 shape 和 arrayOf 一起使用。哪种方法是正确的?在父组件或子组件中定义 PropTypes?也许有更好的主意?请在下面找到我的代码,如果你能告诉我如何使用 PropTypes 就太好了。我试图在网上搜索一些东西,但我仍然没有找到。
主 App.js 文件:
import React from "react";
import "./styles/App.scss";
import List from "./components/List/List";
import AppHeader from "./components/AppHeader/AppHeader";
function App() {
return (
<div className="App">
<AppHeader content="TODO List"></AppHeader>
<List></List>
</div>
);
}
export default App;
AppHeader.js 文件:
import React from "react";
import "./AppHeader.scss";
export default function AppHeader(props) {
return (
<div className="header">
<h1 className="header-headline">{props.content}</h1>
</div>
);
}
List.js 文件:
import React from "react";
import "./List.scss";
import ListItem from "../ListItem/ListItem";
import _ from "lodash";
const initialList = [
{ id: "a", name: "Water plants", status: "done" },
{ id: "b", name: "Buy something to eat", status: "in-progress" },
{ id: "c", name: "Book flight", status: "in-preparation" }
];
const inputId = _.uniqueId("form-input-");
// function component
const List = () => {
const [value, setValue] = React.useState(""); // Hook
const [list, setList] = React.useState(initialList); // Hook
const handleChange = event => {
setValue(event.target.value);
};
// add element to the list
const handleSubmit = event => {
// prevent to add empty list elements
if (value) {
setList(
list.concat({ id: Date.now(), name: value, status: "in-preparation" })
);
}
// clear input value after added new element to the list
setValue("");
event.preventDefault();
};
// remove current element from the list
const removeListItem = id => {
setList(list.filter(item => item.id !== id));
};
// adding status to current element of the list
const setListItemStatus = (id, status) => {
setList(
list.map(item => (item.id === id ? { ...item, status: status } : item))
);
};
return (
<div className="to-do-list-wrapper">
<form className="to-do-form" onSubmit={handleSubmit}>
<label htmlFor={inputId} className="to-do-form-label">
Type item name:
</label>
<input
type="text"
value={value}
onChange={handleChange}
className="to-do-form-input"
id={inputId}
/>
<button type="submit" className="button to-do-form-button">
Add Item
</button>
</form>
<ul className="to-do-list">
{list.map(item => (
<ListItem
name={item.name}
status={item.status}
key={item.id}
id={item.id}
setListItemStatus={setListItemStatus}
removeListItem={removeListItem}
></ListItem>
))}
</ul>
</div>
);
};
export default List;
和ListItem.js文件:
import React from "react";
import PropTypes from "prop-types";
import "./ListItem.scss";
const ListItem = props => {
return (
<li className={"list-item " + props.status} key={props.id}>
<span className="list-item-icon"></span>
<div className="list-item-content-wrapper">
<span className="list-item-text">{props.name}</span>
<div className="list-item-button-wrapper">
<button
type="button"
onClick={() => props.setListItemStatus(props.id, "in-preparation")}
className="button list-item-button"
>
In preparation
</button>
<button
type="button"
onClick={() => props.setListItemStatus(props.id, "in-progress")}
className="button list-item-button"
>
In progress
</button>
<button
type="button"
onClick={() => props.setListItemStatus(props.id, "done")}
className="button list-item-button"
>
Done
</button>
<button
type="button"
onClick={() => props.removeListItem(props.id)}
className="button list-item-button"
>
Remove
</button>
</div>
</div>
</li>
);
};
ListItem.propTypes = {
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
name: PropTypes.string,
status: PropTypes.string,
removeListItem: PropTypes.func,
setListItemStatus: PropTypes.func
};
export default ListItem;
我不确定 propTypes shape
和 arrayOf
会在哪里使用,但一般来说,当您尝试在父组件中呈现子组件时,PropTypes 很有用组件,并且您想在相关子组件的道具上执行 TypeChecking
。
在您的场景中,arrayOf
和 shape
可以用在组件中的一个道具中,其中道具是某种类型的数组 (arrayOf
),并且某种类型的对象(shape
,或exact
)。
道具是每个组件。
道具类型的目的是让您对组件的道具进行一些类型检查。
看来您在 ListItem 组件中做对了。
基本上,您只需列出组件的所有道具以及它们应该是什么类型。
就像你在这里做的那样:
ListItem.propTypes = {
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
name: PropTypes.string,
status: PropTypes.string,
removeListItem: PropTypes.func,
setListItemStatus: PropTypes.func
};
前段时间我尝试在 React 中迈出第一步。现在我正在尝试创建简单的待办事项列表应用程序。我的一位同事告诉我,将 PropTypes 与 shape 和 arrayOf 一起使用会很好。我有一个组件将数据传递给另一个组件,这是我的问题(List.js 和 ListItem.js)。我不确定何时、何地以及如何将 propTypes 与 shape 和 arrayOf 一起使用。哪种方法是正确的?在父组件或子组件中定义 PropTypes?也许有更好的主意?请在下面找到我的代码,如果你能告诉我如何使用 PropTypes 就太好了。我试图在网上搜索一些东西,但我仍然没有找到。
主 App.js 文件:
import React from "react";
import "./styles/App.scss";
import List from "./components/List/List";
import AppHeader from "./components/AppHeader/AppHeader";
function App() {
return (
<div className="App">
<AppHeader content="TODO List"></AppHeader>
<List></List>
</div>
);
}
export default App;
AppHeader.js 文件:
import React from "react";
import "./AppHeader.scss";
export default function AppHeader(props) {
return (
<div className="header">
<h1 className="header-headline">{props.content}</h1>
</div>
);
}
List.js 文件:
import React from "react";
import "./List.scss";
import ListItem from "../ListItem/ListItem";
import _ from "lodash";
const initialList = [
{ id: "a", name: "Water plants", status: "done" },
{ id: "b", name: "Buy something to eat", status: "in-progress" },
{ id: "c", name: "Book flight", status: "in-preparation" }
];
const inputId = _.uniqueId("form-input-");
// function component
const List = () => {
const [value, setValue] = React.useState(""); // Hook
const [list, setList] = React.useState(initialList); // Hook
const handleChange = event => {
setValue(event.target.value);
};
// add element to the list
const handleSubmit = event => {
// prevent to add empty list elements
if (value) {
setList(
list.concat({ id: Date.now(), name: value, status: "in-preparation" })
);
}
// clear input value after added new element to the list
setValue("");
event.preventDefault();
};
// remove current element from the list
const removeListItem = id => {
setList(list.filter(item => item.id !== id));
};
// adding status to current element of the list
const setListItemStatus = (id, status) => {
setList(
list.map(item => (item.id === id ? { ...item, status: status } : item))
);
};
return (
<div className="to-do-list-wrapper">
<form className="to-do-form" onSubmit={handleSubmit}>
<label htmlFor={inputId} className="to-do-form-label">
Type item name:
</label>
<input
type="text"
value={value}
onChange={handleChange}
className="to-do-form-input"
id={inputId}
/>
<button type="submit" className="button to-do-form-button">
Add Item
</button>
</form>
<ul className="to-do-list">
{list.map(item => (
<ListItem
name={item.name}
status={item.status}
key={item.id}
id={item.id}
setListItemStatus={setListItemStatus}
removeListItem={removeListItem}
></ListItem>
))}
</ul>
</div>
);
};
export default List;
和ListItem.js文件:
import React from "react";
import PropTypes from "prop-types";
import "./ListItem.scss";
const ListItem = props => {
return (
<li className={"list-item " + props.status} key={props.id}>
<span className="list-item-icon"></span>
<div className="list-item-content-wrapper">
<span className="list-item-text">{props.name}</span>
<div className="list-item-button-wrapper">
<button
type="button"
onClick={() => props.setListItemStatus(props.id, "in-preparation")}
className="button list-item-button"
>
In preparation
</button>
<button
type="button"
onClick={() => props.setListItemStatus(props.id, "in-progress")}
className="button list-item-button"
>
In progress
</button>
<button
type="button"
onClick={() => props.setListItemStatus(props.id, "done")}
className="button list-item-button"
>
Done
</button>
<button
type="button"
onClick={() => props.removeListItem(props.id)}
className="button list-item-button"
>
Remove
</button>
</div>
</div>
</li>
);
};
ListItem.propTypes = {
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
name: PropTypes.string,
status: PropTypes.string,
removeListItem: PropTypes.func,
setListItemStatus: PropTypes.func
};
export default ListItem;
我不确定 propTypes shape
和 arrayOf
会在哪里使用,但一般来说,当您尝试在父组件中呈现子组件时,PropTypes 很有用组件,并且您想在相关子组件的道具上执行 TypeChecking
。
在您的场景中,arrayOf
和 shape
可以用在组件中的一个道具中,其中道具是某种类型的数组 (arrayOf
),并且某种类型的对象(shape
,或exact
)。
道具是每个组件。
道具类型的目的是让您对组件的道具进行一些类型检查。
看来您在 ListItem 组件中做对了。
基本上,您只需列出组件的所有道具以及它们应该是什么类型。
就像你在这里做的那样:
ListItem.propTypes = {
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
name: PropTypes.string,
status: PropTypes.string,
removeListItem: PropTypes.func,
setListItemStatus: PropTypes.func
};