Ответы пользователя по тегу React
  • Как настроить webpack-dev-server?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    config.devServer = {
        contentBase: path.resolve(__dirname, 'build'),
        compress: false,
        port: 9000,
        historyApiFallback: true,
    };


    output: {
        path: path.resolve(__dirname, 'build'),
        filename: 'bundle.js',
        publicPath: '/',
    },

    Путь до бандла из браузера:
    localhost:9000/bundle.js
    Ответ написан
  • Как из js разорвать строку?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    .header {
      white-space: pre-line;
    }

    Демо.
    Ответ написан
  • Как получить env переменную?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    webpack.DefinePlugin
    module.exports = {
      plugins: [
        new webpack.DefinePlugin({
          __API_URL__: JSON.stringify(process.env.API_URL),
        });
      ],
    };
    Ответ написан
  • Как я могу установить пользовательскую действительность, чтобы в ней была ссылка?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Принцип:
    const Example = () => (
      <div className="form-control">
        <input type="text" name="email" value={email} onChange={handleChange} />
        {isEmailInUse && (
          <div className="error">
            Email address is in use, please select another or <Link to='/signin'>Sign in</Link>
          </div>
        )}
      </div>
    );
    Ответ написан
    4 комментария
  • Как правильно получать данные с сервера в SPA (React + Redux)?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    что делать в этом случае?

    Вам должно быть виднее. Если это данные которые могли измениться, то очевидно, что лучше подтянуть свежие. Если что-то, что меняется редко, то можно проверить наличие в хранилище.
    Еще можно использовать socket соединение и реализовать на сервере логику, чтобы он сам посылал на клиент обновления по мере их появления.
    Ответ написан
    Комментировать
  • Как правильно задать путь к файлу и компоненту?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    В чем причина?

    В том, что вы все делаете неправильно.

    Вам надо использовать клиентский роутинг. Например, react-router-dom.
    React Training / React Router
    Ответ написан
  • Как на react.js взаимодействовать с php?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    1. Вам надо научиться работать в связке Apache/Nginx + PHP. Кроссдоменные запросы нельзя делать из файлов открытых как "file:///"
    2. В React-компонент никак. В шаблон к которому крепится React-приложение можно.
    Ответ написан
    2 комментария
  • Как прокинуть в пропсы компонента данные из store?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    1. mapStateToProps метод для маппинга данных store в свойства компонента. Никаких Promise там быть не должно.
    Насколько я понял их там и нет, это неправильный mapDispatchToProps переопределяет значения, так как возвращает одноименные свойства.

    2. Вызов mapDispatchToProps у вас написан неправильно. Вы просто вызываете actions и возвращаете promise. Еще он переопределяет свойства из mapStateToProps.
    Правильно так:
    const mapDispatchToProps = dispatch => ({
      getMovies: () => dispatch(getMoviesAction()),
      getRecommendations: () => dispatch(getRecommendationsAction()),
    });

    или:
    const mapDispatchToProps = {
      getMovies: getMoviesAction,
      getRecommendations: getRecommendationsAction,
    };


    3. Названия действий лучше изменить:
    getMoviesAction ==> getMovies
    getMovies ==> getMoviesSucceeded


    После переименования actions, mapDispatchToProps сокращается до:
    const mapDispatchToProps = {
      getMovies,
      getRecommendations,
    };
    Ответ написан
    1 комментарий
  • Что не так с map()?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    1. Уберите внутреннее состояние и componentWillMount.
    Нет смысла использовать состояние, если вы его не изменяете, лучше использовать props напрямую.
    В componentWillMount у вас очень плохой код, а сам метод не рекомендован к использованию.

    2.
    render () {
      const { projects } = this.props;
      const activeProjects = projects.filter(project => project.ProjectStatus === "ACTIVE");
    
      const projectsList = activeProjects.map(project => (
        <div key={i} className="focus-projects">
          ...
        </div>
      ));
    
      return (
        ...
      );
    }


    Почему в componentWillMount плохой код:
    1. Вы используете для перебора метод, который надо использовать только для преобразования данных. Для перебора правильно использовать forEach.
    2. Вы выполняете setState для каждого активного проекта в массиве.

    Как было бы правильно:
    this.setState({
      activeProjects: this.props.projects.filter(project.ProjectStatus === "ACTIVE"),
    });
    Ответ написан
    1 комментарий
  • Почему webpack ругается на импорт React компонента?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Замените:
    test: /\.js$/,
    на:
    test: /\.jsx?$/,
    Ответ написан
    Комментировать
  • Как использовать useStore, useSelector, useDispatch hook?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    1. useDispatch - получение функции store.dispatch в компоненте. Раньше для вызова action функциональный компонент приходилось оборачивать в вызов connect:
    const Foo = ({ dispatch }) => {
      const handler = useCallback(() => {
        dispatch(action());
      }, []);
    
      return (
        <Bar onClick={handler} />
      );
    };
    
    export default connect()(Foo);


    Сейчас:
    const Foo = () => {
      const dispatch = useDispatch();
    
      const handler = useCallback(() => {
        dispatch(action());
      }, []);
    
      return (
        <Bar onClick={handler} />
      );
    };
    
    export default Foo;


    2. useSelector - маппинг значения из store.
    Раньше:
    const Foo = ({ value }) => {
      return (
        <Bar value={value} />
      );
    };
    
    const mapStateToProps = state => ({
      value: state.value,
    });
    
    export default connect(mapStateToProps)(Foo);


    const Foo = () => {
      const value = useSelector(state => state.value);
    
      return (
        <Bar value={value} />
      );
    };
    
    export default Foo;


    3. useStore - получение store целиком:
    const valueSelector = state => state.value;
    
    const Foo = () => {
      const { dispatch, getState, subscribe } = useStore();
      const value = valueSelector(getState());
      
      useEffect(() => subscribe(console.log), []);
    
      const handler = useCallback(() => {
        dispatch(action());
      }, []);
    
      return (
        <Bar onClick={handler} value={value} />
      );
    };
    
    export default Foo;

    Вряд ли useStore вам, действительно, понадобится на практике.
    Ответ написан
    Комментировать
  • Как в react-select передать массив для свойства isOptionDisabled?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Вы должны передавать в isOptionDisabled функцию, которая принимает первым аргументом опцию и возвращает Boolean.

    createIsOptionDisabled = disOptions => option =>
      disOptions.some(({ value }) => value === option.value);


    return (
      <Select
        options={options}
        isOptionDisabled={this.createIsOptionDisabled(disOptions)}
      />
    );
    Ответ написан
    Комментировать
  • Как добавить значение в store redux?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Например
    import React, { useCallback, useRef } from 'react';
    import ReactDOM from 'react-dom';
    import { combineReducers, createStore } from 'redux';
    import { Provider, connect } from 'react-redux';
    
    // action type
    const ADD_MESSAGE = 'ADD_MESSAGE';
    
    // action creator
    const addMessage = payload => ({
      type: ADD_MESSAGE,
      payload,
    });
    
    // reducer
    const messages = (state = [], action) => {
      switch (action.type) {
        case ADD_MESSAGE:
          return [...state, action.payload];
        default:
          return state;
      }
    };
    
    // root reducer
    const rootReducer = combineReducers({
      messages,
    });
    
    // store
    const store = createStore(rootReducer);
    
    const App = ({ addMessage, messages }) => {
      const inputRef = useRef(null);
    
      const handler = useCallback(() => {
        addMessage(inputRef.current.value);
        inputRef.current.value = '';
      }, [inputRef, addMessage]);
    
      return (
        <div>
          <ul>
            {messages.map((message, i) => (
              <li key={i}>{message}</li>
            ))}
          </ul>
          <input ref={inputRef} />
          <button onClick={handler}>Add Message</button>
        </div>
      );
    };
    
    const mapStateToProps = state => ({
      messages: state.messages,
    });
    
    const mapDispatchToProps = {
      addMessage,
    };
    
    const ConnectedApp = connect(
      mapStateToProps,
      mapDispatchToProps
    )(App);
    
    const root = (
      <Provider store={store}>
        <ConnectedApp />
      </Provider>
    );
    
    const rootElement = document.getElementById('root');
    ReactDOM.render(root, rootElement);

    Пример с использованием redux-act
    import React, { useCallback, useRef } from 'react';
    import ReactDOM from 'react-dom';
    import { combineReducers, createStore } from 'redux';
    import { Provider, connect } from 'react-redux';
    import { createAction, createReducer } from 'redux-act';
    
    // action creator
    const addMessage = createAction('ADD_MESSAGE');
    
    // reducer
    const messages = createReducer({}, []);
    messages.on(addMessage, (state, message) => [...state, message]);
    
    // root reducer
    const rootReducer = combineReducers({
      messages,
    });
    
    // store
    const store = createStore(rootReducer);
    
    const App = ({ addMessage, messages }) => {
      const inputRef = useRef(null);
    
      const handler = useCallback(() => {
        addMessage(inputRef.current.value);
        inputRef.current.value = '';
      }, [inputRef, addMessage]);
    
      return (
        <div>
          <ul>
            {messages.map((message, i) => (
              <li key={i}>{message}</li>
            ))}
          </ul>
          <input ref={inputRef} />
          <button onClick={handler}>Add Message</button>
        </div>
      );
    };
    
    const mapStateToProps = state => ({
      messages: state.messages,
    });
    
    const mapDispatchToProps = {
      addMessage,
    };
    
    const ConnectedApp = connect(
      mapStateToProps,
      mapDispatchToProps,
    )(App);
    
    const root = (
      <Provider store={store}>
        <ConnectedApp />
      </Provider>
    );
    
    const rootElement = document.getElementById('root');
    ReactDOM.render(root, rootElement);
    Ответ написан
    Комментировать
  • Styled components и className?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Или лучше так

    Почему так делать не стоит:
    1. Страдает изоляция. Любая сторонняя библиотека с ccs может поломать ваш код в самых неожиданных местах.
    2. Возможные проблемы при изменении структуры.
    3. Возможные проблемы при добавлении свойств состояния, от которых будет зависеть верстка. Придется по-старинке плодить селекторы состояния или прокидывать свойства через родителя.

    Если больше нравится второй подход, то стоит посмотреть в сторону css модулей.
    Ответ написан
    Комментировать
  • Как правильно сообщить компоненту Movie, что тот или иной фильм рекомендован?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Суть:
    const recommendation = recommendations.find(({ movieId }) => movieId === movie.id);


    Поиск можно выполнять в селекторе, в колбеке movies.map, при необходимости меморизировать и тд.
    Ответ написан
    2 комментария
  • Как решить данные вопросы по реакту?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    так как вк ведь тоже на react-е

    VK написан не на React. Там может и есть новые React модули, но весь основной функционал написан на ванильном JS.

    но при этом в local storage нет токенов

    VK на web-клиенте хранят токены в HTTP Only Cookie. А ключ для запросов к бэкенду возвращают в коде авторизованной страницы.

    нет данных пользователя

    Что касается данных пользователя, то хранить их в localStorage нет особого смысла. Их можно запрашивать при инициализации приложения.

    Где хранить данные полученные от сервера после авторизации

    Ваше решение должно учитывать требования к безопасности конкретного приложения. Безопасней всего ничего нигде не хранить. На втором месте использование HTTP Only Cookie.

    Как разрешить указывать уникальный url для страницы профиля

    Добавить уникальное поле, например, userName.

    Что бы хотел получить в ответ на вопросы:
    1) Правильно ли у меня сейчас сделано.
    2) Если не правильно, то как сделать правильно.
    3) Литературу, которая бы помогла приблизиться к вк по реализации этого вопроса.
    4) Так же очень сильно хотелось бы узнать, где можно найти литературу, которая бы помогла сделать приложение максимально безопасным.

    1) Ну в теории данные легко украсть, например, с помощью, браузерного расширения, вредоносной библиотеки или если будет дыра, позволяющая выполнить XSS. Если не ошибаюсь, то простые XSS атаки вроде:
    https://site.net/?name=<script>alert(document.cookie)</script>

    давно не работают.
    2) Сложный вопрос и у разных разработчиков на него разные ответы. Изучайте чужой опыт и обсуждения.
    3) Тут разве ждать когда разработчики VK решат написать об этом статью или рассказать о своем опыте на конференции. Еще вы можете самостоятельно заняться реверс инжинирингом их клиента или поискать статьи/посты людей которые им занимались.
    4) Начните с чек-листа по безопасности web-приложения.
    Ответ написан
  • Поведение useMemo между компонентами?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Результат вычислений useMemo привязан к конкретному экземпляру компонента.
    У вас два варианта:
    1. перенести вычисления вверх по древу.
    2. использовать другие инструменты для меморизации.
    Ответ написан
    Комментировать
  • Как запретить перерисовывать компонент при переходе по роутам?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Тут все зависит от ряда факторов:
    1. Если Header находится на страницах, отрисовываемых по определенным маршрутам, то только переносом компонента за пределы Route.

    2. Если он находится за пределами Route и ваше приложение полностью перерисовывается при смене маршрутов, то компонент можно обернуть в React.memo.
    Ответ написан
    Комментировать
  • В чем минусы установки React через подключение скриптов?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Если загружать React и ReactDOM с CDN, а для своего кода использовать бандл собранный Webpack, то вы, возможно, получите такие плюсы, как: уменьшенный размер бандла и повышенную скорость загрузки, так как React и ReactDOM у пользователей возможно будет закеширован. С другой стороны существуют риски попасть в ситуацию, когда CDN по какой-либо причине может быть недоступен.

    Писать приложение в скрипте text/babel лучше не стоит, так как webpack позволяет автоматизировать множество процессов, которые вам придется контролировать самостоятельно, имеет очень удобный инструментарий для разработки, ну и писать поддерживаемый, расширяемый код с ним гораздо проще.
    Ответ написан
    Комментировать
  • Что лучше изучить начинающему vue или react?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Попробуйте обе библиотеки и выберите для изучения ту, которая больше понравится. Написать два Todo List много времени не займет.
    Ответ написан
    Комментировать