• Авторизация в React?

    nakree
    @nakree
    Wondermarin,

    import React from 'react';
    import { Route, Redirect } from 'react-router';
    import { useSelector } from 'react-redux';
    
    import Wrapper from '../wrappers/Wrapper';
    import { PageLoader } from '../ui/layout/Loader';
    import { authSelectors } from '../../modules/auth/authSelectors';
    import { configSelectors } from '../../modules/config/configSelectors';
    import { REQUEST } from '../../config/constants';
    import routing from '../../config/routing';
    
    export default function AuthRoute({ pageName, ...rest }) {
      const isAuth = useSelector(authSelectors.isAuth);
      const { status } = useSelector(authSelectors.getLogin);
    
      if (status === REQUEST) {
        return (
          <Wrapper pageName={pageName}>
            <PageLoader/>
          </Wrapper>
        );
      }
    
      if (!isAuth) {
        return <Redirect to={routing().login} />;
      }
    
      return (
        <Wrapper pageName={pageName}>
          <Route {...rest} />
        </Wrapper>
      );
    }


    //App.jsx
    ...
    <Switch>
        <WrappedRoute exact path={routing().login} component={Login} />
        <AuthRoute exact path={routing().a} component={A} />
        <AuthRoute exact path={routing().b} component={B} />
        <AuthRoute exact path={routing().c} component={C} />
    </Switch>
    ...
    Написано
  • Как подключить React в рабочую папку, и что все работало?

    nakree
    @nakree
    Cyberial Syntwaiser, ну можно самому установить через npm реакт, вебпак, бабель настроить все и подключить к существующему проекту. Но тот способ будет гораздо проще и быстрее
  • Как присвоить className="active" для li?

    nakree
    @nakree
    Smuzzzzzi, изначально добавить класс .active в компоненте. elem.classList.toggle(active)при клике уберет этот класс, если он был, или добавит, если его не было. Ниже Антон Спирин написал более универсальный компонент, который будет подсвечивать нужный li в зависимости от pathname, и я думаю Вам это решение подойдет лучше, потому что здесь нужно еще убирать другие класcы .active и подсвечивать только по клику на нужный.
  • Как присвоить className="active" для li?

    nakree
    @nakree
    Smuzzzzzi, эм, использовать просто <Link/> , и написать банальную функцию:

    сlass Links extends React.Component {
    toggleActive = ({currentTarget}) => {
      currentTarget.classList.toggle('active');
    }
    
    render() {
     <li onClick={this.toggleActive}>
      <Link to="/">
        <u>Главная</u>
      </Link>
    </li>
    <li onClick={this.toggleActive}>
      <Link to="/about">
        <u>О нас</u>
      </Link>
    </li>
    }
    
    }
  • Ка составить план по разработке сайта? Что изучать?

    nakree
    @nakree
    Chloyka, юзерам же нужно знать актуальную информацию про погоду, которую можно взять с апишки, а как только она устареет - то она уже не нужна. Ну собственно и хранить ее не нужно, потому что по запросу можно всегда узнать актуальную. А сервер нужен если есть собственная метеостанция для генерации данных :)
    Ну, соглашусь, что это писать бек может быть интересным в целях обучения в этом случае
  • Ка составить план по разработке сайта? Что изучать?

    nakree
    @nakree
    Chloyka, для такого приложения не нужен сервер. Все данные приходят по аpi, и обрабатываются с помощью js. Ну и базы данных тут точно не нужно
  • Как установить react?

    nakree
    @nakree
    Александр, тогда Вам следует хорошенько погуглить что такое node.js, npm, webpack, babel и как эти вещи связанны с реактом, а затем (при условии хорошего знания нативного js) можно приступать к создании проекта на фреймворке.
  • Как установить react?

    nakree
    @nakree
    Александр, команда начинается с npm, а не с npx.
    npm init react-app my-app создаст в текущей директории папку с названием my-app куда запишет проект с зависимостями.

    У Вас npm установлен?
  • Текст в input number?

    nakree
    @nakree
    В замыкании хранить переменную, которая будет выводится в инпут. На сам инпут повесить обработчик событий нажатий клавиш с e.preventDefault() в начале. Затем записывать нажатую клавишу в эту переменную, при передаче в инпут добавить нужное окончание, типо `${str} шт.`

    Или создать скрытый инпут в который при фокусе на первом инпуте будут записываться введенные значения в скрытый инпут, а в не скрытый будет выводится значение из скрытого с нужной приставкой.
  • Откуда подставляются категории в sidebar (react)?

    nakree
    @nakree
    При беглом осмотре могу предположить что категории берутся из redux хранилища, а попадают туда после выполнения actions.fetchListIfNeeded(); Следовательно, они берутся из какого то запроса от сервера\апишки и тд.
    (А еще этот код очень стремный)
  • А какая архитектура reactjs/redux приложения у вас?

    nakree
    @nakree
    Артём, раньше я делал папки actions, reducers, components, containers. Но, потом понял, что трачу много времени на поиск нужного файла в нужной папке, потому решил попробовать бросать все что нужно компоненту в одну папку и вышло очень удобно, все в одном месте. Если есть какой то код который можно будет переиспользовать, то можно вынести его из папки, допустим в папку common.

    Код и структура из одного и того же проекта
  • А какая архитектура reactjs/redux приложения у вас?

    nakree
    @nakree
    Артём, это собственная функция обёртка вокруг react-s-alert (библиотека которая показывает нотификейшены). Я использую redux-devtools и все в порядке: пишется название экшена USER_DATA_FETCH, а если кликнуть, то можно увидеть payload: {status: 'success' , data: ['test', 'test1', 'test2']}. Для меня это очень удобно, сделать еще один статус для запроса - легко, сделать еще какую то обработку данных в редюсере от другого экшена - легко, сделать аналогичный редюсер просто копируешь, вставляешь, меняешь только название экшена.
  • Нужно ли использовать препроцессоры CSS?

    nakree
    @nakree
    Анатолий Цивилёв, а что нужно объяснять человеку если он спрашивает зачем ему этот инструмент, приводит примеры, и говорит мол и без них все супер и вобще они нинужны?
    В любой статье про препроцессоры описаны их преимущества, и почему это современный маст хев. А Вы просите продублировать содержание этих статей, коих очень много в интернете, и примерно столько же много однотипных вопросов на тостере про препроцессоры. Если Вы не видите смысла использовать препроцессоры, и хотите ручками писать лишний код то пожалуйста.


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


    Достаточно взглянуть как написаны исходники бутстрапа с использованием препроцессоров, и как выглядит сss файл на 9к строк если бы его пришлось писать без них.
  • А какая архитектура reactjs/redux приложения у вас?

    nakree
    @nakree
    Артём,
    redux-actions сокращает количество кода в редюсерах и экшенах примерно в 3 раза
    //action
    export const fetchUserData = createAction('USER_DATA_FETCH');
    
    export const getUserData = (id) => async (dispatch) => {
        dispatch(fetchUserData({status: 'request'}));
        try {
          const res = await api.getUserAccount(id);
          if (res.data.status === 'success') {
            dispatch(fetchUserData({status: 'success', data: res.data.data}));
            return res;
          } else {
            dispatch(fetchUserData({status: 'failure'}));
            notification('error', res.data.message || res.statusText)
          }
        } catch (e) {
          dispatch(fetchUserData({status: 'failure'}))
          notification('error', e.message)
        }
    }
    
    //reducer
    
    const userDataFetchingState = handleActions({
      [actions.fetchUserData](state, {payload}) {
        return payload.status;
      }
    }, 'none');
    
    const userDataFetch = handleActions({
      [actions.fetchUserData](state, {payload}) {
        if (payload.status === 'success') {
          return payload.data;
        } else {
          return state;
        }
      }
    }, {});
    
    const userData = combineReducers({
      status: userDataFetchingState,
      data: userDataFetch
    });
  • Как задать событие изменения input без плагинов но на jquеry?

    nakree
    @nakree
    событие onchange и хендлер который будет выполнять фильтрацию. Рекомендую сделать debounce на 300-400 мс.
    Можно загуглить как js live search.

    P.S. Не увидел кода в котором ошибка или что то не получается.
  • Как установить SASS в проект через npm?

    nakree
    @nakree
    boga-net, да, так можно. Только желательно перед этим удалить папку node_modules, на всякий случай.
    Чтобы заработало, еще нужно добавить этот плагин для создания сss файла и webpack-cli.

    Если нужен готовый пример, то вот мой package.json, лишнее убрал:
    spoiler
    "scripts": {
        "dev": "webpack-dev-server --mode development --open",
        "build": "webpack --mode production"
      },
      "devDependencies": {
        "clean-webpack-plugin": "^0.1.19",
        "css-loader": "^0.28.11",
        "extract-text-webpack-plugin": "^4.0.0-beta.0",
        "file-loader": "^1.1.11",
        "node-sass": "^4.9.0",
        "path": "^0.12.7",
        "sass-loader": "^6.0.7",
        "style-loader": "^0.20.3",
        "webpack": "^4.9.1",
        "webpack-cli": "^2.1.4",
        "webpack-dev-server": "^3.1.4"
      },
      "main": "index.js"



    и webpack.config.js:
    spoiler
    const path = require('path');
    const ExtractTextPlugin = require("extract-text-webpack-plugin");
    const CleanWebpackPlugin = require('clean-webpack-plugin');
    
    const extractSass = new ExtractTextPlugin({
        filename: './css/styles.css',
        disable: process.env.NODE_ENV === 'development'
    });
    
    const bundleAnalyzer = new BundleAnalyzerPlugin({
      analyzerMode: 'server',
      analyzerHost: 'localhost',
      analyzerPort: 8888,
      reportFilename: 'report.html',
      defaultSizes: 'parsed',
      openAnalyzer: process.env.NODE_ENV !== 'development',
      generateStatsFile: false,
      statsFilename: 'stats.json',
      statsOptions: null,
      logLevel: 'info'
    })
    const cleanDist = new CleanWebpackPlugin(['dist']); // чистит /dist при каждом билде
    
    let conf = {
    	entry: './src/index.js',
    	output: {
    		path: path.resolve(__dirname, './dist'),
    		filename: '[name].bundle.js',
    		sourceMapFilename: "sourcemaps/[file].map",
    		publicPath: 'dist/'  // Для webpack-dev-server, чтобы запускать файлы из памяти на лету без build
    	},
    	devServer: {
    		overlay: true		// Если будет ошибка, появится оверлей на странице
    	},
    	module: {
    		rules: [
    			{
    				test: /\.(js|jsx)$/,	// regExp
    				loader: 'babel-loader',
    				exclude: '/node_modules' //исключение
    			},
    			{
    				test: /\.scss$/,
    				use: extractSass.extract({
              fallback: 'style-loader', //если не сработает извлечение, то записать в js
              use: ['css-loader', 'sass-loader']
            })
    			},
    			{
    				test: /\.(png|svg|jpg|gif)$/,
    				use: ['file-loader']
    			},
    			{
    				test: /\.(woff|woff2|eot|ttf|otf)$/,
    				use: ['file-loader']
    			}
    		]
    	},
    	plugins: [
    		cleanDist,
                   extractSass
      ]
    };
    
    module.exports = (env, options) => {
    	let production = options.mode === 'production';
    
    	conf.devtool = production ? 'source-map' : 'eval-sourcemap';
    
    	//смотрим какой mode при запуске, и выбираем какие соурс мапы писать
    	//eval - быстрее, но пишет в итоговый файл(больше вес)
    
    	return conf;
    }