Как условно отобразить атрибут состояния - PullRequest
0 голосов
/ 13 июня 2019

Я пытаюсь получить раскрывающееся меню для отображения названия темы, выбранной пользователем на предыдущей странице (в настоящее время по умолчанию используется значение «Темы»).

Хотя я могу получить $r.state.topics[$r.state.topicSelected].name в консоли, я получаю неопределенную ошибку, когда помещаю this.state.topics[this.state.topicSelected].name в свой код.

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

<select
value={this.state.topicSelected}
onChange={this.onTopicClick}
className="sort"
data-element>
    {
    // Add this option in the .then() when populating siteCategories()
    [<option key={this.state.topicSelected}
      value={this.state.topicSelected}>({if 
       (this.state.topics[this.state.topicSelected].name == undefined) {
       'Topics'
    } else {
    this.state.topics[this.state.topicSelected].name
     }})
    </option>].concat(
this.state.topics.map(function (topic) {
 return (<option
 key={topic.id}
 value={topic.id}>{topic.name}</option>);
  }))
 }
</select>

Я получаю неожиданную ошибку токена, но я попробовал различные комбинации синтаксиса без удачи - как мне правильно запустить это условное форматирование?

Ответы [ 2 ]

2 голосов
/ 13 июня 2019

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

function App() {
  const [topics] = useState(["Math", "Geography"]);
  const [selectedTopic, setSelected] = useState("Topic");
  return (
    <select
      value={selectedTopic}
      onChange={(e) => setSelected(e.target.value)}
      className="sort"
    >
      <option>
        Topic
      </option>
      {topics.map(topic => (
        <option key={topic} value={topic}>
          {topic}
        </option>
      ))}
    </select>
  );
}

Класс Версия компонента

class App extends React.Component {
  state = {
    topics: ["Math", "Geography"],
    selectedTopic: "Topic",
  }

  render() {
    const { selectedTopic, topics } = this.state;
    return (
      <select
      value={selectedTopic}
      onChange={(e) => this.setState({ selectedTopic: e.target.value })}
      className="sort"
      >
      <option>
        Topic
      </option>
      {topics.map(topic => (
        <option key={topic} value={topic}>
          {topic}
        </option>
      ))}
    </select>
    );
  }
}

Также в вашем методе рендеринга вы не можете использовать оператор if, поскольку в нем разрешены только выражения javascript. Если вам нужно использовать условные операторы, используйте тернарный оператор или создайте функцию с блоками if, которую можно вызывать из render. Вы можете прочитать больше о выражениях здесь

2 голосов
/ 13 июня 2019

Вы можете использовать троичное выражение ? :. Вот так

this.state.topics[this.state.topicSelected] ? this.state.topics[this.state.topicSelected].name : 'Topics'

Поскольку undefined является ложным значением, оно вернет «Темы», когда this.state.topics[this.state.topicSelected] не определено.

<select
  value={this.state.topicSelected}
  onChange={this.onTopicClick}
  className="sort"
  data-element>
      <option key={this.state.topicSelected}
        value={this.state.topicSelected}>
        {this.state.topics[this.state.topicSelected] ?
         this.state.topics[this.state.topicSelected].name : 'Topics'}
      </option>
      {this.state.topics.map(function (topic) {
         return (<option key={topic.id} value={topic.id}>{topic.name}</option>);
      })}
</select>

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

render() {
<select
  value={this.state.topicSelected}
  onChange={this.onTopicClick}
  className="sort"
  data-element>
      <option value={0}>Topics</option>
      {this.state.topics.map(topic => 
             <option key={topic.id} value={topic.id}>{topic.name}</option>))}
</select>
}
...