在 React 中,是否有一种优雅的方式在 RESTful edit url 中使用 id 并将相应的对象加载到我的组件的初始状态?
In React, is there an elegant way of using the id in a RESTful edit url and loading the corresponding object into the initial state of my component?
我正在构建 React 16.13 应用程序。我有一个搜索组件 src/components/Search.jsx,它构建搜索结果然后构建一个 URL 来编辑这些结果 ...
renderSearchResults = () => {
const { searchResults } = this.state;
if (searchResults && searchResults.length) {
return (
<div>
<div>Results</div>
<ListGroup variant="flush">
{searchResults.map((item) => (
<ListGroupItem key={item.id} value={item.name}>
{item.name}
<span className="float-right">
<Link to={"/edit/"+item.id}>
<PencilSquare color="royalblue" size={26} />
</Link>
</span>
</ListGroupItem>
))}
</ListGroup>
</div>
);
}
};
render() {
return (
<div className="searchForm">
<input
type="text"
placeholder="Search"
value={this.state.searchTerm}
onChange={this.handleChange}
/>
{this.renderSearchResults()}
</div>
);
}
有没有更优雅的方法来load/pass我要编辑的对象?下面我正在解构 URL 并启动 AJAX 调用,但我正在做的事情似乎有点草率。我熟悉 Angular 解析器,这似乎是一种更清晰的解耦解析 URL 和找到合适对象的逻辑的方法,但下面是我能想到的所有...
src/components/Edit.jsx
import React, { Component } from "react";
import FormContainer from "../containers/FormContainer";
export default class Edit extends Component {
render() {
return <FormContainer />;
}
}
src/containers/FormContainer.jsx
class FormContainer extends Component {
...
componentDidMount() {
let initialCountries = [];
let initialProvinces = [];
let coopTypes = [];
// Load form object, if present in URL
const url = window.location.href;
const id = url.split("/").pop();
fetch(FormContainer.REACT_APP_PROXY + "/coops/" + id)
.then((response) => {
return response.json();
})
.then((data) => {
const coop = data;
coop.addresses.map(address => {
address.country = FormContainer.DEFAULT_COUNTRY_CODE; // address.locality.state.country.id;
});
this.setState({
newCoop: coop,
});
});
您没有发布所有相关代码,但我知道您想要完成什么(如果我错了请纠正我)。您想使用 url 参数中的 id 来获取数据。我认为您正在使用 react-router
。您可以使用此示例来重构您的代码:
import React, { useState, useEffect } from "react";
import {
BrowserRouter as Router,
Switch,
Route,
useParams
} from "react-router-dom";
const REACT_APP_PROXY = "api";
const DEFAULT_COUNTRY_CODE = "20";
// You can use functional components and react hooks in React 16.13 to do everything
// No need for class components any more
function FormContainer() {
// useState hook to handle state in functional components
const [newCoop, setNewCoop] = useState({});
// useParams returns an object of key/value pairs of URL parameters. Use it to access match.params of the current <Route>.
const { id } = useParams();
// This will be called whenever one of the values in the dependencies array (second argument) changes
// but you can pass an empty array to make it run once
useEffect(() => {
fetch(REACT_APP_PROXY + "/coops/" + id)
.then(response => {
return response.json();
})
.then(data => {
const coop = data;
coop.addresses.map(address => {
address.country = DEFAULT_COUNTRY_CODE; // address.locality.state.country.id;
});
setNewCoop(coop);
});
// use an empty array as the second argument to run this effect on the first render only
// it will give a similar effect to componentDidMount
}, []);
return <div>Editing {id}</div>;
}
const Edit = () => <FormContainer />;
function App() {
return (
<Router>
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/edit/:id">
<Edit />
</Route>
</Switch>
</Router>
);
}
我正在构建 React 16.13 应用程序。我有一个搜索组件 src/components/Search.jsx,它构建搜索结果然后构建一个 URL 来编辑这些结果 ...
renderSearchResults = () => {
const { searchResults } = this.state;
if (searchResults && searchResults.length) {
return (
<div>
<div>Results</div>
<ListGroup variant="flush">
{searchResults.map((item) => (
<ListGroupItem key={item.id} value={item.name}>
{item.name}
<span className="float-right">
<Link to={"/edit/"+item.id}>
<PencilSquare color="royalblue" size={26} />
</Link>
</span>
</ListGroupItem>
))}
</ListGroup>
</div>
);
}
};
render() {
return (
<div className="searchForm">
<input
type="text"
placeholder="Search"
value={this.state.searchTerm}
onChange={this.handleChange}
/>
{this.renderSearchResults()}
</div>
);
}
有没有更优雅的方法来load/pass我要编辑的对象?下面我正在解构 URL 并启动 AJAX 调用,但我正在做的事情似乎有点草率。我熟悉 Angular 解析器,这似乎是一种更清晰的解耦解析 URL 和找到合适对象的逻辑的方法,但下面是我能想到的所有...
src/components/Edit.jsx
import React, { Component } from "react";
import FormContainer from "../containers/FormContainer";
export default class Edit extends Component {
render() {
return <FormContainer />;
}
}
src/containers/FormContainer.jsx
class FormContainer extends Component {
...
componentDidMount() {
let initialCountries = [];
let initialProvinces = [];
let coopTypes = [];
// Load form object, if present in URL
const url = window.location.href;
const id = url.split("/").pop();
fetch(FormContainer.REACT_APP_PROXY + "/coops/" + id)
.then((response) => {
return response.json();
})
.then((data) => {
const coop = data;
coop.addresses.map(address => {
address.country = FormContainer.DEFAULT_COUNTRY_CODE; // address.locality.state.country.id;
});
this.setState({
newCoop: coop,
});
});
您没有发布所有相关代码,但我知道您想要完成什么(如果我错了请纠正我)。您想使用 url 参数中的 id 来获取数据。我认为您正在使用 react-router
。您可以使用此示例来重构您的代码:
import React, { useState, useEffect } from "react";
import {
BrowserRouter as Router,
Switch,
Route,
useParams
} from "react-router-dom";
const REACT_APP_PROXY = "api";
const DEFAULT_COUNTRY_CODE = "20";
// You can use functional components and react hooks in React 16.13 to do everything
// No need for class components any more
function FormContainer() {
// useState hook to handle state in functional components
const [newCoop, setNewCoop] = useState({});
// useParams returns an object of key/value pairs of URL parameters. Use it to access match.params of the current <Route>.
const { id } = useParams();
// This will be called whenever one of the values in the dependencies array (second argument) changes
// but you can pass an empty array to make it run once
useEffect(() => {
fetch(REACT_APP_PROXY + "/coops/" + id)
.then(response => {
return response.json();
})
.then(data => {
const coop = data;
coop.addresses.map(address => {
address.country = DEFAULT_COUNTRY_CODE; // address.locality.state.country.id;
});
setNewCoop(coop);
});
// use an empty array as the second argument to run this effect on the first render only
// it will give a similar effect to componentDidMount
}, []);
return <div>Editing {id}</div>;
}
const Edit = () => <FormContainer />;
function App() {
return (
<Router>
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/edit/:id">
<Edit />
</Route>
</Switch>
</Router>
);
}