Как обновить состояние реакции - PullRequest
1 голос
/ 17 июня 2020

У меня есть список результатов моего поиска. Каждый результат имеет функцию onclick. Я хочу отображать каждый из результатов, которые нажимает пользователь, и сейчас я могу добавить каждый результат, который пользователь нажимает, в массив с помощью этой функции:

let selectedData = []

function addFunc(resultdata){
    console.log(resultdata)
    selectedData = [...selectedData, resultdata]
    console.log(selectedData)
  };

Я новичок в React, но я знаю, что это неправильный путь, и мне, возможно, придется использовать состояния или реагировать на ловушки. Проблема в том, что, поскольку я использую Elasticsearch для вывода результатов, мои результаты находятся в функции, а не в основном классе. Примерно так:

class Search extends Component {
    render() {
      return (
        <div>
          <ReactiveBase
          app="datataglist"
          credentials="mRgWyoKGQ:f47be2a6-65d0-43b6-8aba-95dbd49eb882"
          url="https://scalr.api.appbase.io"
          >
              <DataSearch
              componentId="search"
              dataField={[
                  "maker_tag_name",
                  "maker_tag_name.autosuggest",
                  "maker_tag_name.keyword"
                ]}
                fieldWeights={[6, 2, 6]}
                fuzziness={1}
                highlightField={["maker_tag_name"]}
                placeholder="Search Tag Name"
                style={{
                    marginBottom: 20
                }}
                title="Maker Tag Name"
                />
                <Row gutter={16}>
                    <Col span={8}>
                        <MultiList
                            componentId="system"
                            dataField="system.keyword"
                            queryFormat="or"
                            size={100}
                            sortBy="asc"
                            style={{
                            marginBottom: 20
                            }}
                            title="System"
                        />
                    </Col>
                    <Col span={8}>
                        <MultiList
                            componentId="grouping"
                            dataField="grouping.keyword"
                            size={100}
                            style={{
                            marginBottom: 20
                            }}
                            title="Grouping"
                        />
                    </Col>
                    <Col span={8}>
                        <MultiList
                            componentId="unit"
                            dataField="units.keyword"
                            size={100}
                            style={{
                            marginBottom: 20
                            }}
                            title="Unit"
                        />
                    </Col>
                  </Row>
                  <SelectedFilters /> 
                  <ReactiveList
                    componentId="results"
                    dataField="_score"
                    pagination={true}
                    react={{
                        and: ["system", "grouping", "unit", "search"]
                    }}
                    size={10}
                    noResults="No results were found..."
                    renderItem={RenderItem}
                     />
          </ReactiveBase>
          <div>
          </div>
          </div>
      );
  }
}

function getNestedValue(obj, path) {
    const keys = path.split(".");
    const currentObject = obj;
    const nestedValue = keys.reduce((value, key) => {
      if (value) {
        return value[key];
      }
      return "";
    }, currentObject);
    if (typeof nestedValue === "object") {
      return JSON.stringify(nestedValue);
    }
    return nestedValue;
  }


  function RenderItem(res, triggerClickAnalytics) {
    let { unit, title, system, score, proposed, id } = {
      title: "maker_tag_name",
      proposed: "proposed_standard_format",
      unit: "units",
      system: "system",
      score: "_score",
      id: "_id"
    };
    title = getNestedValue(res, title);
    system = getNestedValue(res, system);
    unit = getNestedValue(res, unit);
    score = getNestedValue(res, score);
    proposed = getNestedValue(res, proposed);
    id = getNestedValue(res, id);

    const resultdata = {id, title, system, unit, score, proposed}

      return (
        <Row
          onClick={triggerClickAnalytics}
          type="flex"
          gutter={16}
          key={res._id}
          style={{ margin: "20px auto", borderBottom: "1px solid #ededed" }}
        >
          <Col style={{ width: "360px" }}>
            <h3
              style={{ fontWeight: "600" }}
              dangerouslySetInnerHTML={{
                __html: title || "Choose a valid Title Field"
              }}
            />
          </Col>
          <div style={{ padding: "20px" }} />
          <Col>
              <p
              style={{ fontSize: "1em", width: "300px" }}
              dangerouslySetInnerHTML={{
              __html: system || "Choose a valid Description Field"
              }}
              />
          </Col>
          <div style={{ padding: "10px" }} />
          <Col>
          <p
              style={{ fontSize: "1em" }}
              dangerouslySetInnerHTML={{
                __html: unit || "-"
              }}
            />
          </Col>
          <div style={{ padding: "10px" }} />
          <Col style={{ minWidth: "120px" }}>
            <p
              style={{ fontSize: "1em", width: "300px"}}
              dangerouslySetInnerHTML={{
                __html: proposed || "Choose a valid Description Field"
              }}
            />
          </Col>
          <div style={{ padding: "10px" }} />
          <Col>
            <p
              style={{ fontSize: "1em"}}
              dangerouslySetInnerHTML={{
                __html: Math.round(score) || "Choose a valid Description Field"
              }}
            />
          </Col>
          <Col>
              <Button
                shape="circle"
                icon={<CheckOutlined />}
                style={{ marginRight: "5px" }}
                onClick={()=> {addFunc(resultdata)}}
              />
          </Col>
        </Row>
      );
  }

По сути, мой ReactiveList компонент - это то, что показывает результаты. Это вызывает функцию RenderItem, которая отображает данные на экране. В моей функции у меня есть список под названием resultdata, который содержит все данные, которые мне нужны при нажатии на каждый результат. Это работает, но мне нужно, чтобы это отображалось на экране.

Я не могу использовать состояние, потому что у меня есть функция. И я не могу использовать хуки, потому что это не основная функция. Я делаю что-то неправильно? Есть ли другая альтернатива этому?

Даже если вы не можете дать исчерпывающий ответ, я был бы признателен за любые советы о том, в каком направлении мне следует смотреть.

Ответы [ 2 ]

1 голос
/ 17 июня 2020

состояние asyn c, поэтому оно не будет обновляться следующим образом:

function addFunc(resultdata){
    console.log(resultdata)
    selectedData = [...selectedData, resultdata]
    console.log(selectedData)
  };

и вы используете класс, поэтому вы не можете useHooks, но setState принимает обратный вызов в качестве второго аргумента

function addFunc(resultdata){
    console.log(resultdata)
    this.setState({selectedData: [...selectedData, resultdata]}, () => console.log(selectedData))
  };

, поэтому, если вы продолжите использовать подход Class, это позволит вам использовать setState и использовать в нем обратный вызов

, в хуках также доступен обратный вызов, но он не не работает точно так же

0 голосов
/ 17 июня 2020

Поместите addFun c в родительский компонент и сделайте вашу функцию RenderItem функциональным компонентом React, экспортируя ее. Затем укажите addFun c в качестве опоры функции от родительского компонента к компоненту RenderItem. Таким образом, вы можете вызвать функцию в событии onClick. Любое из родительских состояний может быть обновлено из addFun c. Вы также можете указать необходимые аргументы для вызова функции.

...