Как я могу объявить переменную в скобках? - PullRequest
0 голосов
/ 16 января 2019

У меня есть функция рендеринга, подобная этой:

render() {
    const statement = true
    return (
      <div>
        {
          statement &&
          <div>
            <p>
              {this.buildStuff()}
            </p>
            <p>
              {this.buildStuff()}
            </p>
            <p>
              {this.buildStuff()}
            </p>
          </div>
        }
      </div>
    );
  }

Чтобы не вызывать buildStuff() три раза, я бы хотел присвоить ее переменной.Как я могу объявить переменную после строки с statement &&?

Быстрое решение было бы сделать

const statement = true
const stuff = statement ? buildStuff() : null;

, но это решение использует две ветви вместо одной.

Вы можете попробовать этот код на StackBlitz .

Вот как это будет выглядеть в Razor .

Ответы [ 4 ]

0 голосов
/ 16 января 2019

Этот ответ является ответом на проблему, но не решением вопроса. Если вы не можете объявить переменную внутри скобок в реакции (как вы могли бы сделать, например, в Razor). Лучше всего сделать ставку дважды, сделав выписку.

render() {
    const statement = true
    const stuff = statement ? this.buildStuff() : null
    return (
      <div>
        {
          statement &&
          <div>
            <p>
              {stuff}
            </p>
            <p>
              {stuff}
            </p>
            <p>
              {stuff}
            </p>
          </div>
        }
      </div>
    );
  }

По крайней мере, мы вызываем this.buildStuff() только в случае необходимости, а если мы делаем, мы вызываем его только один раз.

0 голосов
/ 16 января 2019

Вы можете попробовать что-то вроде этого:

  • Вы можете создать функцию, которая работает с этим представлением пользовательского интерфейса.
  • В этой функции вы можете вызвать buildStuff и вернуть ей 3 <p> тегов.
  • Затем в основном рендере вы можете проверить свое состояние и сделать рендеринг соответственно. Это сделает ваш рендер чистым и декларативным.
getBuildJSX() {
  const stuff = this.buildStuff();
  return Array.from({ length: 3}, () => <p> { stuff }</p>);
}

render() {
  const statement = true
  return (
    <div>
      {
        statement ? this.getBuilsJSX() : null
      }
    </div>
  );
}

Попробуйте онлайн

0 голосов
/ 16 января 2019

Первое решение (редактировать: альтернатива)

render() {
    const statement = true;
    const stuff = this.buildStuff(statement, 3); // jsx result looped in divs
    return (
      <div>
        {
          statement &&
          <div>
            { stuff }
          </div>
        }
      </div>
    );
  }

Альтернатива, запоминание (кэширование функций), если это ваша цель:

const memoize = require('fast-memoize');
const memoized = memoize(this.buildStuff);


...

render() {
    const statement = true; 
    return (
      <div>
        {
          statement &&
          <div>
            <p>
              {memoized()}
            </p>
            <p>
              {memoized()}
            </p>
            <p>
              {memoized()}
            </p>
          </div>
        }
      </div>
    );
  }

Однако истинная сила запоминания заключается в том, что если вы кешируете на основе параметра, который вы указываете buildStuff (может быть, вы переместите оператор в buildstuff?). В вашем случае я бы просто очистил компонент и параметры для удобства чтения, а не для оптимизации чего-либо. Итак, последний вариант:

// Stuff is a component now
const Stuff = ({statement, stuff}) => {
  if(!statement)
    return null;

  const result = stuff();

  return (
    <div>   
      <p>
        {result}
      </p>
      <p>
        {result}
      </p>
      <p>
        {result}
      </p>
    </div>
  )
}

render() {
    return (
      <div>
        <Stuff statement={true} stuff={this.buildStuff} />
      </div>
    );
  }

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

Единственный ответ на ваш вопрос в заголовке: вы не можете, JSX не шаблонизатор, как Razor.

Пояснение:

// JSX  
<div id="foo">Hello world</div>

// Translates into 
React.createElement("div", {id: "foo"}, "Hello world");

// JSX
<div>{ statement && <div /> }</div>

// Translates to
React.createElement("div", null, statement && React.createElement("div"));

Либо вы объявляете новую переменную с атрибутом, либо просто не можете, поскольку javascript не позволяет создавать переменные внутри параметров функций.

0 голосов
/ 16 января 2019

Я думаю, что одна из основных идей реагирования - это использование компонентов для структурирования вашего кода.

Так что один из способов сделать это был бы так:

render() {
    const statement = true;

    const Stuff = ({statement}) => {
      if (!statement) { return null; }
      return this.buildStuff();
    }

    return (
      <div>
        <p>
          <Stuff statement={statement} /> 
        </p>
        <p>
          <Stuff statement={statement} />
        </p>
        <p>
          <Stuff statement={statement} />
        </p>
      </div>
    );
  }

Обновлено StackBlitz .

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