Skip to content

Instantly share code, notes, and snippets.

@u88803494
Created January 7, 2020 15:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save u88803494/3769d179f413cd998b3601f870402687 to your computer and use it in GitHub Desktop.
Save u88803494/3769d179f413cd998b3601f870402687 to your computer and use it in GitHub Desktop.
w23 Redux 補充部分,很多邏輯打包,一樣用反斜線替代資料結構
import * as actionTypes from './actionTypes';
export const updateNavText = (text) => {
return {
type: actionTypes.UPDATE_NAV_TEXT,
value: text,
};
};
export const getPosts = () => ({
type: actionTypes.GET_POSTS,
});
export const getPostsSuccess = (data) => ({
type: actionTypes.GET_POSTS_SUCCESS,
data,
});
export const UPDATE_NAV_TEXT = "UPDATE_NAV_TEXT";
export const UPDATE_TEST = "UPDATE_TEST";
export const GET_POSTS = "GET_POSTS";
export const GET_POSTS_SUCCESS = "GET_POSTS_SUCCESS";
.App {
text-align: center;
}
.page {
margin-top: 100px;
}
import React, { Component } from 'react';
import './App.css';
import Nav from './containers/NavContainer';
import About from './component/about/';
import Home from './containers/HomeContainer';
import PostList from './containers/PostsContainer';
import Post from './component/post';
import { BrowserRouter as Router, Route } from "react-router-dom";
class App extends Component {
render() {
return (
<Router>
<div className="App" >
<Nav />
<div className="page">
<Route exact path="/" component={Home} />
<Route exact path="/post" component={PostList} />
<Route path="/about" component={About} />
<Route path="/post/:postId" component={Post} />
</div>
</div>
</Router>
);
}
}
export default App;
.about {
background: rgba(0, 255, 0 , 0.3);
min-height: calc(100vh - 74px);
}
.about > div {
font-size: 36px;
margin: 10px;
}
import React, { Component } from 'react';
import './About.css';
class About extends Component {
render() {
return (
<div className="about">
<div>About</div>
<div>hello</div>
</div>
);
}
}
export default About;
.homepage {
font-size: '40px';
padding-top: '10px';
}
import React, { Component } from 'react';
import './home.css';
class Home extends Component {
render() {
return (
<div className="home">
<div className="homepage">I am homepage</div>
<button onClick={
() => {
this.props.updateNav(Math.random())
}
}>click me</button>
</div>
);
}
}
export default Home;
import Nav from './Nav';
export { Nav as default };
.nav {
position: fixed;
top: 0;
left: 0;
right: 0;
background: #bbbbbb;
opacity: 0.8;
z-index: 2;
}
.nav__list {
list-style: none;
padding: 0;
text-align: left;
margin-left: 20px;
}
.nav__list li {
display: inline-block;
margin-right: 16px;
background: rgba(255, 0, 0, 0.3);
padding: 10px;
transition: background 0.3s;
cursor: pointer;
}
.nav__list a {
text-decoration: none;
color: black;
}
.nav__list li:hover {
background: rgba(255, 0, 0, 0.5);
}
.nav__list .active {
background: rgba(255, 0, 0, 0.5);
}
import React, { Component } from 'react';
import './Nav.css';
import { Link, Route } from "react-router-dom";
class Item extends Component {
render() {
const { to, text, exact } = this.props;
return (
<Route
path={to}
exact={exact}
children={({ match }) => (
<Link to={to}>
<li className={match ? "active" : ""}>
{text}
</li>
</Link>
)}
/>
)
}
}
class Nav extends Component {
render() {
return (
<nav className="nav" >
<ul className="nav__list">
<Item to='/' exact={true} text='Home' />
<Item to='/post' text='文章列表' />
<Item to='/about' text='關於本站' />
</ul>
<div>{this.props.navText}</div>
</nav>
);
}
}
export default Nav;
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { getPost } from '../../WebAPI'
class Posts extends Component {
constructor(props) {
super(props);
this.state = {
post: {},
}
}
componentDidMount() {
const { postId } = this.props.match.params;
getPost(postId)
.then(res => {
this.setState({
post: res.data,
})
})
}
render() {
const { post } = this.state;
return (
<div>
<h1>POST</h1>
<Link to="/post"><button> back </button> </Link>
<div>
<h1>{post.title ? post.title : 'Loading'}</h1>
<p>{post.body}</p>
</div>
</div>
);
}
}
export default Posts;
import React, { Component } from 'react';
import './Post.css';
class PostList extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
this.props.getPostList();
}
render() {
const { history, posts } = this.props;
return (
<div>
<h1>POST</h1>
<div className="post-list">
{posts.map(post => (
<div className="post-item" key={post.id}>
<div className="post-item__id" onClick={() => {
history.push("/post/" + post.id)
}}>{post.id}</div>
<div className="post-item__title"> {post.title}</div>
<div className="post-item__body">{post.body}</div>
</div>
))}
</div>
</div>
);
}
}
export default PostList;
.post-list {
display: flex;
flex-wrap: wrap;
margin: auto;
margin-left: 10px;
}
.post-item {
position: relative;
width: 200px;
height: 200px;
background: rgba(255, 255, 0, 0.1);
margin-right: 10px;
margin-bottom: 10px;
overflow: hidden;
}
.post-item__id {
position: absolute;
left: 0;
right: 0;
width: 20px;
height: 20px;
display: flex;
justify-content: center;
align-items: center;
background: red;
}
.post-item__title {
margin-top: 15px;
font-size: 30px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
import React from 'react';
import { connect } from 'react-redux';
import Home from '../component/home';
import { updateNavText } from '../actions';
const HomeContainer = (props) => {
return <Home {...props} />
}
const mapDispatchToPtops = dispatch => {
return {
updateNav: text => dispatch(updateNavText(text)),
}
}
export default connect(null, mapDispatchToPtops)(HomeContainer);
import React from 'react';
import { connect } from 'react-redux';
import Nav from '../component/nav/';
const NavContainer = (props) => {
return <Nav {...props} />
}
const mapStateToProps = state => {
return {
navText: state.nav.navText
}
}
export default connect(mapStateToProps)(NavContainer);
import React from 'react';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import Posts from '../component/post_list';
import * as WebAPI from '../WebAPI';
import * as actions from '../actions'
const PostsContainer = (props) => {
return <Posts {...props} />
}
const mapStateToProps = state => {
return {
isLoadingGetPosts: state.nav.isLoadingGetPosts,
posts: state.nav.posts,
}
}
const mapDispatchToProps = dispatch => {
return {
getPostList: () => {
dispatch(actions.getPosts())
WebAPI.getPosts().then(res => {
dispatch(actions.getPostsSuccess(res.data))
})
}
}
}
export default withRouter(
connect(mapStateToProps, mapDispatchToProps)(PostsContainer)
);
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import { Provider } from 'react-redux';
import { createStore, combineReducers } from 'redux';
import navReducer from './reducer';
const reducers = combineReducers({
nav: navReducer,
});
const store = createStore(reducers);
ReactDOM.render(
<Provider store={store}>
<App name="hugh" />
</Provider>, document.getElementById('root'));
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
import * as actionTypes from './actionTypes';
const state = {
navText: '123',
isLoadingGetPosts: false,
posts: [],
}
// [].reduce()
function reducer(globalState = state, action) {
switch (action.type) {
case actionTypes.UPDATE_NAV_TEXT:
return {
...globalState,
navText: action.value,
};
case actionTypes.UPDATE_TEST:
return {
...globalState,
test: action.value,
};
case actionTypes.GET_POSTS:
return {
...globalState,
isLoadingGetPosts: true,
};
case actionTypes.GET_POSTS_SUCCESS:
return {
...globalState,
isLoadingGetPosts: false,
posts: action.data
};
default:
return globalState;
}
}
export default reducer;
import axios from 'axios';
export const getPosts = () =>
axios.get('https://jsonplaceholder.typicode.com/posts');
export const getPost = postId =>
axios.get('https://jsonplaceholder.typicode.com/posts/' + postId);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment