Skip to content

Instantly share code, notes, and snippets.

@u88803494
Last active January 3, 2020 11:37
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/31a9fa84f87546f1333b6f512bd45539 to your computer and use it in GitHub Desktop.
Save u88803494/31a9fa84f87546f1333b6f512bd45539 to your computer and use it in GitHub Desktop.
w23 學習 redux 的 blog
.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;
import { UPDATE_NAV_TEXT } from './actionTypes';
export const updateNavText = (text) => {
return {
type: UPDATE_NAV_TEXT,
value: text,
};
};
export const UPDATE_NAV_TEXT = "UPDATE_NAV_TEXT";
export const UPDATE_TEST = "UPDATE_TEST";
.App {
text-align: center;
}
.page {
margin-top: 100px;
}
import React, { Component } from 'react';
import './App.css';
import NavContainer from './nav';
import About from './about';
import Home from './home';
import PostList from './post_list';
import Post from './post';
import { BrowserRouter as Router, Route } from "react-router-dom";
class App extends Component {
render() {
return (
<Router>
<div className="App" >
<NavContainer />
<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;
.homepage {
font-size: '40px';
padding-top: '10px';
}
import React, { Component } from 'react';
import './home.css';
import { connect } from 'react-redux'
import { updateNavText } from '../actions';
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>
);
}
}
const mapDispatchToPtops = dispatch => {
return {
updateNav: text => dispatch(updateNavText(text)),
}
}
export default connect(null, mapDispatchToPtops)(Home);
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 NavContainer from './NavContainer';
export { NavContainer 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 from 'react';
import { connect } from 'react-redux';
import Nav from './Nav'
const NavContainer = (props) => {
console.log('navCon');
return <Nav {...props} />
}
const mapStateToProps = state => {
return {
navText: state.nav.navText
}
}
export default connect(mapStateToProps)(NavContainer);
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import axios from 'axios';
class Post extends Component {
constructor(props) {
super(props);
this.state = {
post: {},
}
}
componentDidMount() {
const { postId } = this.props.match.params;
axios.get('https://jsonplaceholder.typicode.com/posts/' + 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 Post;
import React, { Component } from 'react';
import { withRouter } from 'react-router-dom';
import axios from 'axios';
import './Post.css';
class PostList extends Component {
constructor(props) {
super(props);
this.state = {
posts: [],
}
}
componentDidMount() {
axios.get('https://jsonplaceholder.typicode.com/posts')
.then(res => {
this.setState({
posts: res.data,
})
})
}
render() {
const { posts } = this.state;
const { history } = 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 withRouter(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 { UPDATE_NAV_TEXT, UPDATE_TEST } from './actionTypes';
const state = {
navText: '123',
}
// [].reduce()
function reducer(globalState = state, action) {
switch (action.type) {
case UPDATE_NAV_TEXT:
return {
...globalState,
navText: action.value,
};
case UPDATE_TEST:
return {
...globalState,
test: action.value,
};
default:
return globalState;
}
}
export default reducer;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment