React의 route 설정을 리팩토링해보고, createRef() 를 사용하지 않고 form을 변경해 본다.
- react-router v4에 맞는 redux 환경 재구성
- react-final-form 적용하기
- 사용자별 Link 목록 보여주기
- 적용소스
React Router v4에 맞는 Redux 설정
react-router-redux는 react router v2와 v3에 맞는 패키지이고 react router v4에 맞는 connected-react-router로 교체해야 한다. recct-router-redux 설정 상태로는 redux action이 작동하지 않는다.
// 설치
$ meteor npm install --save connected-react-router
// 삭제
$ meteor npm uninstall --save react-router-redux
$ meteor npm uninstall --save @types/react-router-redux
imports/ui/store.ts 리팩토링
- Routes.tsx의 browserHistory 를 store.ts로 옮김
- connectRouter로 routerReducer를 생성
- RouterAction, LocationChangeAction을 추가
import { createBrowserHistory } from 'history';
import { connectRouter, RouterAction, LocationChangeAction } from 'connected-react-router';
export const browserHistory = createBrowserHistory();
const rootReducer = combineReducers({
router: connectRouter(browserHistory),
links: linkReducer
});
export type RootState = StateType<typeof rootReducer>;
type ReactRouterAction = RouterAction | LocationChangeAction;
export type RootAction = ReactRouterAction | LinkAction;
imports/ui/Routes.tsx 리팩토링
- react-router v4의 Router를 사용하지 않고, connected-react-router의 ConnectedRouter를 사용
- 인자로 store.ts 에서 생성한 browserHistory를 사용
import { ConnectedRouter } from 'connected-react-router';
import store, { browserHistory } from './store';
export const Root = (
<Provider store={store}>
<ConnectedRouter history={browserHistory}>
<Switch>
<Route exact path="/" component={Login} />
<Route path="/main" component={App} />
<Route path="/signup" component={Signup} />
<Route path="/links" component={InfoContainer} />
<Route path="*" component={NotFound} />
</Switch>
</ConnectedRouter>
</Provider>
);
이제 Redux Chrome Extension에서 LOCATION_CHANGE 액션을 볼 수 있다.
final-form 통해 입력
form 관련부분을 final-form으로 변경한다. React버전의 react-final-form을 사용한다.
$ meteor npm install --save final-form
$ meteor npm install --save react-final-form
로그인 화면부터 react-final-form으로 변경해 본다.
- react-final-form의 Form, Field import
- Form 의 onSubmit={this.onLogin}을 통해 입력한 values 객체를 받기, 보통 폼 필드의 name을 key로하여 json 객체를 받는다.
- <input> 태그를 <Field> 태그로 변경
- <button> 태그에 disabled 속성추가
- 필요없는 부분 추석처리: React.createRef()
import * as React from 'react';
import { Link } from 'react-router-dom';
import { Meteor } from 'meteor/meteor';
import { Form, Field } from 'react-final-form';
export interface LoginProps {
history: any;
}
export interface LoginState {
error: string;
}
export default class Login extends React.Component<LoginProps, LoginState> {
// email: any = React.createRef();
// password: any = React.createRef();
constructor(props) {
super(props);
this.state = {
error: ''
};
}
onLogin = ({email, password}) => {
// e.preventDefault();
// let email = this.email.current.value.trim();
// let password = this.password.current.value.trim();
if (!email || !password) {
this.setState({error: 'Please input email and password both'});
return;
}
Meteor.loginWithPassword({ email }, password, (err) => {
if (err) {
this.setState({ error: err.reason });
} else {
this.setState({ error: '' });
}
});
}
makeForm = ({ handleSubmit, submitting, pristine, values }) => {
return (
<form onSubmit={handleSubmit}>
<Field name="email" component="input" type="email" placeholder="Email" required/>
<Field name="password" component="input" type="password" placeholder="Passowrd"/>
{/* <input type="email" ref={this.email} name="email" placeholder="Email" />
<input type="password" ref={this.password} name="password" placeholder="Password" /> */}
<button type="submit" disabled={submitting || pristine}>Login</button>
</form>
);
};
public render() {
return (
<div>
<h1>Login to short Link</h1>
{this.state.error ? <p>{this.state.error} </p> : undefined}
<Form onSubmit={this.onLogin} render={this.makeForm} />
<Link to="/signup">Have a account?</Link>
</div>
);
}
}
Signup.tsx, AddLink.tsx 도 변경한다.
사용자별 Link 목록 보여주기
사용자를 추가하여 각 사용자가 등록한 목록만 보기 위해서 pub/sub 설정에서 userId 파라미터를 넘겨주어 본인 목록만 조회하여 publish 한다.
// imports/ui/Info.tsx 맨 하단의 subscribe시에 자신의 아이디를 파라미터로 보낸다.
export default compose(
withTracker(() => {
const connection = Meteor.subscribe('links', {userId: Meteor.userId()});
return {
links: Links.find().fetch(),
loading: !connection.ready()
};
}),
connect(mapProps)
)(Info);
imports/api/links.ts에서 userId를 파라미터로 find한다.
if (Meteor.isServer) {
Meteor.publish('links', ({userId}) => {
console.log('userId:', userId);
if (!userId) {
return this.ready();
}
return Links.find({owner: userId});
});
...
}
<참조>
'Meteor > React + Meteor' 카테고리의 다른 글
[React + Meteor] 개발환경 설정 - 7 (0) | 2018.12.04 |
---|---|
[React + Meteor] 개발환경 설정 - 6 (0) | 2018.12.03 |
[React + Meteor] 개발환경 설정 - 4 (0) | 2018.11.28 |
[React + Meteor] 개발환경 설정 - 3 (0) | 2018.11.22 |
[React + Meteor] 개발환경 설정 - 2 (0) | 2018.11.16 |