在 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>
  );
}