我是React的新手,我的代码有问题。我将尝试描述我所拥有的。
首先,我尝试创建一个简单的“待办事项”列表应用程序,以向每个添加的任务添加/更改状态。
以下是一些代码:
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></AppHeader>
<List></List>
</div>
);
}
export default App;
List.js代码
import React from "react";
import "./List.scss";
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" }
];
// 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 handleClick = id => {
console.log(id);
setList(list.filter(item => item.id !== id));
};
// adding status to current element of the list
const setElementStatus = (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}>
<input
type="text"
value={value}
onChange={handleChange}
className="to-do-form-input"
/>
<button type="submit" className="button to-do-form-button">
Add Item
</button>
</form>
<ul className="to-do-list">
{list.map(item => (
<li className={"to-do-list-element " + item.status} key={item.id}>
<span className="to-do-list-text">{item.name}</span>
<button
type="button"
onClick={() => setElementStatus(item.id, "in-preparation")}
className="button to-do-list-button"
>
In preparation
</button>
<button
type="button"
onClick={() => setElementStatus(item.id, "in-progress")}
className="button to-do-list-button"
>
In progress
</button>
<button
type="button"
onClick={() => setElementStatus(item.id, "done")}
className="button to-do-list-button"
>
Done
</button>
<button
type="button"
onClick={() => handleClick(item.id)}
className="button to-do-list-button"
>
Remove
</button>
</li>
))}
</ul>
</div>
);
};
export default List;
暂时可以,但是我认为为列表元素创建单独的组件可能是一个好主意,我做了类似的事情:
List.js代码
import React from "react";
import "./List.scss";
import ListItem from "../ListItem/ListItem";
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" }
];
// 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 handleClick = id => {
console.log(id);
setList(list.filter(item => item.id !== id));
};
// adding status to current element of the list
const setElementStatus = (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}>
<input
type="text"
value={value}
onChange={handleChange}
className="to-do-form-input"
/>
<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}
></ListItem>
))}
</ul>
</div>
);
};
export default List;
我被添加了新的组件,代码在这里:
import React from "react";
import "./ListItem.scss";
import List from "../List/List";
const ListItem = item => {
return (
<li className={"to-do-list-element " + item.status} key={item.id}>
<span className="to-do-list-text">{item.name}</span>
<button
type="button"
onClick={() => List.setElementStatus(item.id, "in-preparation")}
className="button to-do-list-button"
>
In preparation
</button>
</li>
);
};
export default ListItem;
问题是,如何从ListItem.js组件中的List.js组件触发功能?
答案 0 :(得分:2)
在List.js代码中,您可以将函数作为道具传递给ListItem组件,例如
{list.map(item => (
<ListItem
name={item.name}
status={item.status}
key={item.id}
yourFunction={whateverFunction}
></ListItem>
))}
然后在您的ListItem
中传递道具,其中将包含yourFunction
,然后是name, status
和key
。
说您通过了道具,这意味着ListItem看起来像:
const ListItem = props => {...}
您可以只调用执行props.yourFunction()
的函数。
OR
您可以破坏正在传递的道具,例如:
const ListItem = ({yourFunction, name, status, key}) => {...}
然后立即在组件中使用它,而无需添加道具(例如yourFunction()
)。