Некоторые фишки React
Начинающие JS-программисты часто ругают React за большое количество кода, несмотря на то, что есть масса возможностей писать его в достаточно сжатом виде. Итак перечислим некоторые из них.
Условный рендеринг
Вместо вот таких записей:
render() { if (flag) { return <div> <Inner /> </div> } else { return <div/> } }
всегда можно записать вот так:
render() { return <div> {flag && <Inner />} </div> }
Массивы элементов
Что только не пишут с массивами:
render() { let list = []; for (let i = 0; i < this.props.text.length; ++i) { list.push(<li key={i}> // key нужен, чтобы отличать элементы массива {this.props.text[i]} </li>) } return <ul> {list} </ul> }
Есть замечательный новый метод .map()
Посмотрите на аргументы передаваемой функции
render() { return <ul> {this.props.text.map((item, i) => <li key={i}>{item}</li>)} </ul> }
Массив элементов из метода render
Раздутый JS-код может распространяться дальше и на HTML-разметку. Например, так случилось, что из метода render() нам необходимо вернуть несколько элементов. Часто для этого заводится элемент, в котором располагается массив элементов:
render() { return <div class="unnecessary"> <div class="row1"/> <div class="row2"/> </div> }
Вместо этого, можно использовать React.Fragment:
render() { return <React.Fragment> <div class="row1"/> <div class="row2"/> </React.Fragment> }
или совсем сокращённую запись:
render() { return <> <div class="row1"/> <div class="row2"/> </> }
Стрелочные компоненты
Если у вашего компонента вдруг не оказалось внутреннего state и хуков, то вместо
class MyComponent extends React.Component { render() { return <div>{this.props.text}</div> } }
можно написать стрелочный компонент (!):
const MyComponent = (props) => <div>{props.text}</div>
Стрелочные компоненты обладают рядом преимуществ, и вместо «дополнительных render-методов» в классе большого компонента вы просто можете просто вынести разметку в отдельные компоненты.
Destructuring
Данная возможность ES6 позволяет немного сократить код. И вместо этого
class MyComponent extends React.Component { render() { return <div className={this.props.className}> {this.props.text} </div> } }
можно писать
class MyComponent extends React.Component { render() { const {className, text} = this.props; return <div className={className}>{text}</div> } }
В стрелочных компонентах такое сокращение выглядит более эпично:
const MyComponent = (props) => ( <div className={props.className}> {props.text} </div> );
преобразуется в:
const MyComponent = ({className, text}) => ( <div className={className}> {text} </div> );
Redux, а точнее redux-connect
В большинстве примеров по redux-connect присутствует такая запись:
const mapStateToProps = state => { return { todos: getVisibleTodos(state.todos, state.visibilityFilter) } } const mapDispatchToProps = dispatch => { return { onTodoClick: id => { dispatch(toggleTodo(id)) } } } const VisibleTodoList = connect( mapStateToProps, mapDispatchToProps )(TodoList) export default VisibleTodoList
Эту запись можно смело переписать не только таким образом:
export default connect( state => ({ // чтобы arrow возвращала литерал объекта - ставим скобки () todos: getVisibleTodos(state.todos, state.visibilityFilter) }), dispatch => ({ onTodoClick: id => dispatch(toggleTodo(id)) }) )(TodoList)
Но и вовсе используя декораторы:
@connect(state => ({ todos: getVisibleTodos(state.todos, state.visibilityFilter) }), dispatch => ({ onTodoClick: id => dispatch(toggleTodo(id)) })) export default class TodoList { // ...
Это, разумеется, только основы, и в программе курса «Разработчик JavaScript» мы разбираем многие другие интересности!
Есть вопрос? Напишите в комментариях!