setState не обновляет значок шрифта awesome

Я пытаюсь динамически отображать отличный значок шрифта в написанном мной компоненте флажка. Когда я пытаюсь обновить состояние значка font awesome после нажатия на него, он не обновляется. Я попытался переместить рендеринг в отдельную функцию и попытался использовать response-fontawesome, но ничего не помогает. Состояние обновляется, но значки font awesome - это тот же код svg в html.

...
state = {
 checked: this.props.checked
}

toggleCheck = () => {
  this.setState({ checked: !this.state.checked });  
};

render () {

  const iconUnchecked = 'far fa-square';
  const iconChecked = 'fas fa-check-square';
  const iconClass = this.state.checked ? iconChecked : iconUnchecked;

  return (
    <span onClick={this.toggleCheck}>
      <i className={iconClass} />
    </span>
  );
}

person 200OK    schedule 18.04.2018    source источник
comment
я думаю, вы пропустили здесь const iconUnchecked = 'far fa-square' должно быть const iconUnchecked = 'fas fa-square';   -  person Giang Le    schedule 18.04.2018
comment
Проблема все та же   -  person 200OK    schedule 18.04.2018
comment
Прежде всего измените iconClass на let, потому что вы хотите изменить его в будущем.   -  person Sergey    schedule 18.04.2018


Ответы (3)


Как я понял, font awesome js управляет DOM, а React - виртуальным DOM. Когда font awesome js выполняет свои собственные функции, React не может повторно отрендерить его после изменения состояния. Я все еще использую React 15, и, возможно, это не проблема React 16. Я только что нашел решение, чтобы поместить каждый with font awesome в div с уникальным ключом. Таким образом, React увидит, что div должен измениться, потому что был изменен ключ.

person 200OK    schedule 19.04.2018
comment
Ключевым моментом здесь является размещение опоры key на содержащем элементе, не на элементе, к которому применен класс font-awesome. <button key='unique'><i className={'fas' + condition ? 'fa-eye' : 'fa-edit'} /></button> - person Ben Steward; 16.03.2020
comment
да, работал хорошо, вы действительно можете использовать this.state.checked как уникальный ключ - person Dheeraj; 06.08.2020

Попробуйте это https://jsfiddle.net/n5u2wwjg/30533/

Для меня вроде работает

Проверь точно, jsfiddle работает, а не фрагмент. Сниппет просто нужен редактору.

class TodoApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      checked: this.props.checked
    }
    this.toggleCheck = this.toggleCheck.bind(this);
  }
  
  toggleCheck() {
    this.setState({ checked: !this.state.checked });  
  }
  
  render() {
    const iconUnchecked = 'far fa-square';
  	const iconChecked = 'fas fa-check-square';
  	let iconClass = this.state.checked ? iconChecked : iconUnchecked;

    return (
      <span onClick={this.toggleCheck}>
        <i className={iconClass} />
      </span>
    )
  }
}

ReactDOM.render(<TodoApp />, document.querySelector("#app"))
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

.done {
  color: rgba(0, 0, 0, 0.3);
  text-decoration: line-through;
}

input {
  margin-right: 5px;
}
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.10/css/all.css" integrity="sha384-+d0P83n9kaQMCwj8F4RJB66tzIwOKmrdb46+porD/OvrJ+37WqIM7UoBtwHO6Nlg" crossorigin="anonymous">

<div id="app"></div>

person Sergey    schedule 18.04.2018

Я тоже столкнулся с той же проблемой. Как правильно упомянул 200Ok, svg - inline-fa не является виртуальной DOM, поэтому он никогда не обновляется. Лучший способ решить проблему - обернуть элементы font awesome, которые будут содержать решающие классы.

person Tarun    schedule 21.04.2019