These are chat archives for dev-ua/reactjs

26th
May 2017
Nikita
@RedDevilHat
May 26 2017 03:35
Всем привет
Bohdan
@bogdan8
May 26 2017 07:49
ку
Nikita
@RedDevilHat
May 26 2017 08:25

ребят такой вопрос. связка React + Mobx

import { observable, action } from 'mobx';

class UserStore {

    constructor() {
        const me = observable({
            me: null,
            auth: action.bound(function(me) {
                this.me = me;
            })
        })
    }
}

export default UserStore;

index.js

const stores = {
    // Key can be whatever you want
    routing: routingStore,
    UserStores
};

ReactDOM.render(
    <Provider {...stores}>
        <Router history={history}>
            <Entry/>
        </Router>
    </Provider>,
    document.getElementById('root')
);

App.Js

const App = inject('routing','UserStore')(observer(class App extends Component {
    constructor(props, context) {
        super(props, context);
        this.handleFiles = this.handleFiles.bind(this);
        this.state = {excel: null};
    }

    render() {
        const {location, push, goBack} = this.props.routing;
        const {userStore} = this.props.userStore;

        if(userStore.me === null) {
            console.log('lolUserlol');
        }
Store 'UserStore' is not available! Make sure it is provided by some Provider
Вот такая ошибка
как лечить?
Illia Seheda
@ALF-er
May 26 2017 09:05
index.js строка 4, опечатка видимо
Nikita
@RedDevilHat
May 26 2017 09:07
@ALF-er
теперь TypeError: Cannot read property 'userStore' of undefined
C:\Users\rny\WebstormProjects\untitled\src\App\index.js:20
  17 |        this.state = {excel: null};
  18 |    }
  19 | 
> 20 |    render() {
  21 |        const {location, push, goBack} = this.props.routing;
  22 |        const {userStore} = this.props.userStore;
Illia Seheda
@ALF-er
May 26 2017 09:08
предположу, что ты хотел написать
const {UserStore} = this.props;
Dima Bildin
@bildja
May 26 2017 09:08
И плюс имена свойств/переменных case sensitive
Nikita
@RedDevilHat
May 26 2017 09:09
@bildja @ALF-er
×
TypeError: Cannot read property 'me' of undefined
App.render
C:\Users\rny\WebstormProjects\untitled\src\App\index.js:24
  21 |        const {location, push, goBack} = this.props.routing;
  22 |        const {userStore} = this.props;
  23 | 
> 24 |        if(userStore.me === null) {
  25 |            console.log('lolUserlol');
  26 |        }
Dima Bildin
@bildja
May 26 2017 09:09
Ещё раз про case sensitive
Nikita
@RedDevilHat
May 26 2017 09:10
@bildja @ALF-er
спасибо вам
просто я JS не знаю, React не знаю, Mobx не знаю, а писать заставили
Dima Bildin
@bildja
May 26 2017 09:11
Что за времена пошли
Illia Seheda
@ALF-er
May 26 2017 09:11
Надеюсь, у тебя есть достаточные причины не говорить им "Наймите специалиста в этой области, у меня другая специализация"
Nikita
@RedDevilHat
May 26 2017 09:12
страшные, толи дело раньше было, HTML + CSS т полетели
Viktor Kenyz
@Skakruk
May 26 2017 09:12
Software Engineer повинен вміти писати на будь-чому)
Illia Seheda
@ALF-er
May 26 2017 09:12
на санскрите, например
Nikita
@RedDevilHat
May 26 2017 09:13
ну скажем так, ряд причин есть.
Ребят, а такой вопрос
import React, {Component} from 'react';
import NavBar from '../Layout/NavBar';
import { Button } from 'react-bootstrap';

class Login extends Component {
    render() {
        return (
            <div>
                <NavBar/>
                <div>
                    <form className="form-horizontal" id="form">
                        <div className="form-group">
                            <label htmlFor="email" className="col-sm-2 control-label">Введите email</label>
                            <div className="col-sm-10">
                                <input className="form-control" type="email" name="email" id="email"/>
                            </div>
                        </div>
                        <div className="form-group">
                            <label htmlFor="password" className="col-sm-2 control-label">>Введите пароль</label>
                            <div className="col-sm-10">
                                <input className="form-control" type="password" name="password" id="password"/>
                            </div>
                        </div>
                        <div className="form-group">
                            <div className="col-sm-10 col-sm-offset-2">
                                <Button type="submit" className="btn btn-primary">Login</Button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
    );
    }
    }

    export default Login
как мне заставить мой экшон auth дернутся?
Чото тяжело идет практическое применение Mobx'a
Terry Sahaidak
@terrysahaidak
May 26 2017 09:15
<Button onClick={action}>Login</Button>
<Button onClick={() => action()}>Login</Button>
або так
Dima Bildin
@bildja
May 26 2017 09:16
Только лучше <form onSubmit)
Terry Sahaidak
@terrysahaidak
May 26 2017 09:16
ну або так
не побачив шось тегу форми
Nikita
@RedDevilHat
May 26 2017 09:16
@terrysahaidak и как мне указать конкретный? вот у меня прокинута UserStore, у него action auth
как его указать?
Terry Sahaidak
@terrysahaidak
May 26 2017 09:17
прокинути йому стор
Dima Bildin
@bildja
May 26 2017 09:17
@RedDevilHat уверен, где-то тут есть примеры как сделать https://mobx.js.org/refguide/action.html
Terry Sahaidak
@terrysahaidak
May 26 2017 09:17
<form onSubmit={this.props.UserStore.auth}
Nikita
@RedDevilHat
May 26 2017 09:17
@terrysahaidak спасибо большое
Terry Sahaidak
@terrysahaidak
May 26 2017 09:17
пено якось так
Nikita
@RedDevilHat
May 26 2017 09:18
@bildja мне там тяжело сейчас разбиратся, из-за того что @ не работает
Terry Sahaidak
@terrysahaidak
May 26 2017 09:18
а взагалі, імхо, оце кончений брєд
class UserStore {

    constructor() {
        const me = observable({
            me: null,
            auth: action.bound(function(me) {
                this.me = me;
            })
        })
    }
}
Nikita
@RedDevilHat
May 26 2017 09:18
@terrysahaidak это да
Dima Bildin
@bildja
May 26 2017 09:19
Ну тут либо придётся разобраться либо сдаться)
Terry Sahaidak
@terrysahaidak
May 26 2017 09:19
шось не розумію як воно працює взагалі
Nikita
@RedDevilHat
May 26 2017 09:22
@terrysahaidak
как то так я хотел
import { observable, action } from 'mobx';
import asiox from 'axios';

class UserStore {

    constructor() {
        const me = observable({
            me: null,
            auth: action.bound(function(form) {
                axios.post('url', {
                    username: form.username,
                    password: form.username
                })
                    .then(function (response) {
                        this.me = response
                    })
                    .catch(function (response) {
                        alert('No');                        
                    });
            })
        })
    }
}

export default UserStore;
Viktor Tiutiun
@vittorioVT
May 26 2017 09:22
всем привет! подскажите плиз, а router react - это составная redux'a?
Dima Bildin
@bildja
May 26 2017 09:23
Нет
Viktor Tiutiun
@vittorioVT
May 26 2017 09:24
его уже отдельно выделили? Или он изначально был отдельно?)
Illia Seheda
@ALF-er
May 26 2017 09:24
изначально. Его позже с потугами подружили с редаксом
Viktor Tiutiun
@vittorioVT
May 26 2017 09:26
спасибо
Terry Sahaidak
@terrysahaidak
May 26 2017 09:26
constructor() {
        this.me = observable({
хіба так
тоді у тебе буде доступ до цього me через UserStore.me.auth
XaveScor
@XaveScor
May 26 2017 09:27

Hi.

const Auth = ({hasError}) => {
    const error = (hasError === true)
        ? <div>error</div>
        : null

    console.log(hasError)

    return (
        <div>
            <AuthForm />
            <AuthDomain />
            {error}
        </div>
    );
}

export default connect(
    store => ({
        hasError: store.global.invalidRequest
    }),
    dispatch => ({})
)(Auth)

Почему не перерендеривается компонент при изменении store.global.invalidRequest?

Terry Sahaidak
@terrysahaidak
May 26 2017 09:27
а взагалі підключи собі якось декоратори, з ними буде простіше
Nikita
@RedDevilHat
May 26 2017 09:27
у меня не работают декораторы
я проект собрал с помощью creat-react-app
и bable не починил это
Viktor Kenyz
@Skakruk
May 26 2017 09:28
Eject?
Terry Sahaidak
@terrysahaidak
May 26 2017 09:29
завжди вважав cra дніщєм і буду так вважати і надалі
Dima Bildin
@bildja
May 26 2017 09:29
Да без еджекта должно работать, установить и добавить в .babelrc, два действия
Dmytro
@d1monster
May 26 2017 09:29
Всім привіт.
Dima Bildin
@bildja
May 26 2017 09:29

завжди вважав cra дніщєм і буду так вважати і надалі

потому что он декораторы не настроил по умолчанию?)

Terry Sahaidak
@terrysahaidak
May 26 2017 09:29
тому що його кастомізовують через жопу)
Nikita
@RedDevilHat
May 26 2017 09:30
поцоны
Terry Sahaidak
@terrysahaidak
May 26 2017 09:30
про це була доповідь навіть на kyivjs, але, наче, вона тоді не записалась норм
Nikita
@RedDevilHat
May 26 2017 09:30
я ставил babel и делал babelrc
вот проект
Viktor Kenyz
@Skakruk
May 26 2017 09:30
I do think we should look into supporting customisation of the babel, eslint and webpack configs in some way, but that's a larger discussion.
Nikita
@RedDevilHat
May 26 2017 09:31
да я читал, вот и делаю всякими окольными путями
Terry Sahaidak
@terrysahaidak
May 26 2017 09:32

потому что он декораторы не настроил по умолчанию?)

а декоратори сам не юзаю і вам не раджу
будуть хоч на stage 3 тоді подумаю
а так в топку

Dima Bildin
@bildja
May 26 2017 09:33
Ну про CRA спорно. Можно сгенерировать проект, сделать eject и дальше делать что хочешь. А можно пользоваться тем, что есть и не кастомизироваться.
Я хз, я не пользовался им на самом деле, у нас тут другое похожее, но я не считаю это днищем)
Viktor Kenyz
@Skakruk
May 26 2017 09:33
я поки немав проблем з ними
Dima Bildin
@bildja
May 26 2017 09:33
И декораторы норм, рекомендую)
Nikita
@RedDevilHat
May 26 2017 09:34
реебят, я под себя насрал
Illia Seheda
@ALF-er
May 26 2017 09:34
понатягали своей явы в наш яваскрипт, а ещё с шуток на эту тему смеются
Nikita
@RedDevilHat
May 26 2017 09:34
                    <form className="form-horizontal" id="form" onSubmit={UserStore.auth(serialize(document.querySelector('#form'), {hash: true}))}>
TypeError: UserStore.auth is not a function
Viktor Kenyz
@Skakruk
May 26 2017 09:34
в onSubmit передаєш референс
Dima Bildin
@bildja
May 26 2017 09:34
Ну в джаве это вроде аннотации и они на сам код особо не влияют, так что это не совсем, как там)
Nikita
@RedDevilHat
May 26 2017 09:35
import { observable, action } from 'mobx';
import axios from 'axios';

class UserStore {

    constructor() {
        const me = observable({
            me: null,
            auth: action.bound(function(form) {
                axios.post('url', {
                    username: form.username,
                    password: form.username
                })
                    .then(function (response) {
                        this.me = response
                    })
                    .catch(function (response) {
                        alert('No');
                    });
            })
        })
    }
}

export default UserStore;
Viktor Kenyz
@Skakruk
May 26 2017 09:35
а так - ти одразу на рендері викликаєш цю функцію
Terry Sahaidak
@terrysahaidak
May 26 2017 09:35
:point_up: 26 мая 2017 г., 12:26
@RedDevilHat
class UserStore {

    constructor() {
        const me = observable({ // won't work

      this.me = observable({ // will work
Nikita
@RedDevilHat
May 26 2017 09:37
TypeError: Cannot read property 'auth' of undefined
import { observable, action } from 'mobx';
import axios from 'axios';

class UserStore {

    constructor() {
        this.me = observable({
            me: null,
            auth: action.bound(function(form) {
                axios.post('url', {
                    username: form.username,
                    password: form.username
                })
                    .then(function (response) {
                        this.me = response
                    })
                    .catch(function (response) {
                        alert('No');
                    });
            })
        })
    }
}

export default UserStore;
<form className="form-horizontal" id="form" onSubmit={UserStore.me.auth(serialize(document.querySelector('#form'), {hash: true}))}>
@terrysahaidak
Viktor Kenyz
@Skakruk
May 26 2017 09:39
треба створити інстанс цього класу
Nikita
@RedDevilHat
May 26 2017 09:39
@Skakruk супер. Осталось понять как
Dima Bildin
@bildja
May 26 2017 09:40
@RedDevilHat выдели себе какое-то время, почитай про джаваскрипт, разберись, как это работает
Nikita
@RedDevilHat
May 26 2017 09:40
@bildja я как раз в выходные сяду
только эту хрень добить надо
Dima Bildin
@bildja
May 26 2017 09:40
Так сначала разберись, а потом пытайся что-то писать) Так не будет эффективно
Nikita
@RedDevilHat
May 26 2017 09:41
как я понимаю из-зжа того что я передал параметр он вызывает функцию при загрузке странице а не при субмите
@bildja не мне добить сию хрень хочетсо
а бизнесс просит
одно хорошо, для демо это, ане в продакшен
Viktor Kenyz
@Skakruk
May 26 2017 09:42
const stores = {
    // Key can be whatever you want
    routing: routingStore,
    userStore: new UserStores()
};
Nikita
@RedDevilHat
May 26 2017 09:43
@Skakruk Вуухуу, так тут меньше магии чем я думал
спасибо
Viktor Kenyz
@Skakruk
May 26 2017 09:44
class Login extends Component {
    handleSubmit = (e) => {
        e.preventDefault();
        this.props.userStore.me.auth(//data here)
    }, 
    render() {

….

<form className="form-horizontal" id="form" onSubmit={this.handleSubmit}>
Bohdan Denysiuk
@Kotuhan
May 26 2017 09:45

@RedDevilHat когда ты пишешь что-то вроде <Component onAction /* click, submit, etc */={someFunc(...arguments)} /> то ты сразу же вызываешь эту функцию и в обработчик попадет уже результат выполнения функции. В onAction (submit в том числе) нужно передавать ФУНКЦИЮ, а не результат выполнения фунции.

const myFunc = (event) => console.log('Hi there', event);
<Component onSubmit={someFunc} />

Viktor Kenyz
@Skakruk
May 26 2017 09:45
напевно якось так) я з мобх не працював ще
@Kotuhan після ваніла джс це мене дивувало трошки
Nikita
@RedDevilHat
May 26 2017 09:45
@Skakruk да должно отработать, только сбиндить this надо в функцию
Viktor Kenyz
@Skakruk
May 26 2017 09:46
там вже має бути ок
якщо так оголошувати метод, то this буде мати контекс інстансу класу
Bohdan Denysiuk
@Kotuhan
May 26 2017 09:47
@RedDevilHat ты можешь использовать arrow functions - и не нужно писать в конструкторе что-то типа this.myFunc = this.myFunc.bind(this);
Nikita
@RedDevilHat
May 26 2017 09:47
@Kotuhan т.е. с arrow не надо? Ок)
И правда не надо)
спасибо ребята)
Bohdan Denysiuk
@Kotuhan
May 26 2017 09:56
@RedDevilHat если эта фунция рассчитана на то чтобы взаимодейстовать только с этим классом - почему нет?) Только стоит помнить, что у arrow functions нельзя поменять контекст
Terry Sahaidak
@terrysahaidak
May 26 2017 10:22
@RedDevilHat я б викинув cra, клонував оцю штуку і на основі неї шось би робив
https://github.com/mobxjs/mobx-react-boilerplate
XaveScor
@XaveScor
May 26 2017 10:45
Ребята и девчата, кто-нибудь может о бъяснить почему могут не обновляться компоненты при изменении стейта?
Я использую redux
Viktor Kenyz
@Skakruk
May 26 2017 10:45
код в студію
XaveScor
@XaveScor
May 26 2017 10:46
const Auth = ({hasError}) => {
    const error = (hasError === true)
        ? <div>error</div>
        : null

    return (
        <div>
            <AuthForm />
            <AuthDomain />
            {error}
        </div>
    );
}

export default connect(
    store => ({
        hasError: store.app.auth.auth.invalidRequest,
        all: store.app.auth
    }),
    dispatch => ({})
)(Auth)
@Skakruk кроме кода компонента что ещё надо прислать?
Viktor Kenyz
@Skakruk
May 26 2017 10:48
store.app.auth.auth.invalidRequest - точно auth.auth?
XaveScor
@XaveScor
May 26 2017 10:49
Да, это кривой стор пока. Я ещё не совсем разобралсяс как проектировать реакт приложения.
Viktor Kenyz
@Skakruk
May 26 2017 10:49
а сама функція викликається?
XaveScor
@XaveScor
May 26 2017 10:49
Поэтому сделал иерархию стейтов компонентов.
@Skakruk Прости, я не знаю украинского. Ты про вызывается? В сторе, если насильно false поставить, то да, див выводится.
Viktor Kenyz
@Skakruk
May 26 2017 10:51
значит не в компоненте проблема? может где-то экшн не обновляет стор
XaveScor
@XaveScor
May 26 2017 10:52
@Skakruk Я вызываю console.log в редьюсере. Стейт изменяется. Вот этом и проблема. Не понимаю куда копать совершенно.
Viktor Kenyz
@Skakruk
May 26 2017 10:54
редьюсер в студію)
XaveScor
@XaveScor
May 26 2017 10:57
import { combineReducers } from 'redux'

import authFormReducer from './AuthForm/AuthFormReducer'

const initialState = {
  invalidRequest: false
} 

const _authReducer = (store=initialState, action) => {
  console.log(store)
  switch(action.type) {
    case 'INVALID_AUTH':
      store.invalidRequest = true
      break
    default:
      break
  }

  return store
}

const authReducer = combineReducers({
  authForm: authFormReducer,
  auth: _authReducer 
})

export default authReducer
XaveScor
@XaveScor
May 26 2017 11:09
сверчки)
Viktor Kenyz
@Skakruk
May 26 2017 11:27
case 'INVALID_AUTH':
      store.invalidRequest = true
тут проблема - ты должен возращать новый стор, а не модифицировать существующий
switch(action.type) {
    case 'INVALID_AUTH’: 
      return {
           …store,
           invalidRequest: true
      }
    default:
      return store;
  }
XaveScor
@XaveScor
May 26 2017 11:33
Спасибо.
Ivan Daniluk
@divan
May 26 2017 12:01

Всем привет. Пытаюсь вкурить redux на простом примере - есть компонент App и есть компонент Drawer:
App.js:

...
import { toggleSidebar } from './actions';
...
render() {
 return (
             <AppBar onLeftIconButtonTouchTap={toggleSidebar}
          />
   )
}
...
export default App;

Drawer.js:

...
 render() {
    (
        <Drawer open={this.props.open}> </Drawer>
    )
 }

Drawer.propTypes = {
    open: PropTypes.bool.isRequired
}

const mapStateToProps = (state, props) => ({
    open: state.drawerOpen
});

export default connect(mapStateToProps)(Drawer);

Есть action - toggleSidebar:

export const TOGGLE_SIDEBAR = 'TOGGLE_SIDEBAR';

export const toggleSidebar = () => ({
    type: TOGGLE_SIDEBAR,
});

есть reducer:

import { TOGGLE_SIDEBAR  } from '../actions';

const defaultState = {
    drawerOpen: false,
};

export default (previousState = defaultState, { type }) => {
    switch (type) {
        case TOGGLE_SIDEBAR:
            console.log("TOGGLE_SIDEBAR triggered");
            return { ...previousState, drawerOpen: !previousState.drawerOpen };
        default:
            return previousState;
    }
};

Как сделать, чтобы в App при onLeftIconButtonTouchTap диспатчился action toggleSibar? Пробую делать с mapDispatchToProps и bindActionCreators, но пока что не заводится.

Ivan Daniluk
@divan
May 26 2017 12:14
Разобрался. Добавил в app.js:
onLeftIconButtonTouchTap={this.props.onToggleSidebar}
...
const mapDispatchToProps = (dispatch) => {
    return {onToggleSidebar: bindActionCreators(toggleSidebar, dispatch)}
}

export default connect(null, mapDispatchToProps)(App);
Denis Stoyanov
@xgrommx
May 26 2017 12:36
@terrysahaidak +100500 про кря-кря от абрамова