Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# parcel-react-app
`Auth by Liuliu`

it is reference to parcel-react, and it includes

Expand All @@ -8,6 +9,13 @@ it is reference to parcel-react, and it includes
* axios
* react and react dom

# DEMO
## Todo List
![](https://media.giphy.com/media/Tk2KNru0pYD6dHxSB1/giphy.gif)
## OMDB API
![](https://media.giphy.com/media/3XDiHqGVO48qghRTwi/giphy.gif)


## install

* node v10.15.x is required
Expand Down
8 changes: 8 additions & 0 deletions src/api/movie.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import axios from 'axios'

module.exports = {
async requestMovieInfo (search = "Batman") {
const {data : info} = await axios.get(`http://www.omdbapi.com/?s=${search}&apikey=34472924`)
return info
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果沒有要重複給值的話,建議可以用 const 做宣告

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果沒有要重複給值的話,建議可以用 const 做宣告

了解~ 想請問 let 和 const有性能或其他方面上的差異嗎?

}
}
68 changes: 62 additions & 6 deletions src/app.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,94 @@
import React from "react";
import ReactDOM from "react-dom";
import Header from './components/Header';
import Todo from './components/Todo';
import api from './api/base';
import InputSearch from "./components/InputSearch"
import Movie from "./api/movie";
import Product from "./components/Product";
import NavBar from "./components/NavBar"



class HelloMessage extends React.Component {

constructor(props) {
super(props);

this.pageList = ["Movie", "Todo"];
this.state = {
todos: []
todos: [],
movies: [],
showPage: "Movie",
};

}

async searchKwd (keyword) {
if (!keyword) keyword = "banana";

this.setState({
movies: await Movie.requestMovieInfo(keyword)
})
}

setShowPage (pageName) {
this.setState({
showPage : pageName
})
}

pageSwitch () {
const { todos, movies } = this.state
let show = ''

switch (this.state.showPage) {
case "Todo" :
show = <Todo todos = {todos} />
break

case "Movie" :
show = <div>
<InputSearch inputKwd = {(keyword) => this.searchKwd(keyword)} />
<Product movies = {movies} />
</div>
break

default :
show = <div>
<h1>Something Wrong...</h1>
</div>
}

return show
}

async componentDidMount() {
const todos = await api.reloadTodoDatas();
const movies = await Movie.requestMovieInfo();

this.setState({
todos
todos,
movies
});
}

render() {
const { todos } = this.state;
const show = this.pageSwitch()

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

建議會將這一大段拉出來成為一個 function 或者一個 Show component 來處理, 這樣在閱讀的時候會更為輕鬆容易

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

確實是這樣,我改好了!

return (
<div>
<Header/>
<NavBar pageList = {this.pageList} setChoose = {(pageName) => this.setShowPage(pageName)}/>
{/* <Header/> */}
<div className="container">
<h1>Hi {this.props.name}</h1>
{show}

<p>by {this.props.name}.</p>
</div>
</div>
);
}
}

const App = document.getElementById("app");
ReactDOM.render(<HelloMessage name="Caesar" />, App);
ReactDOM.render(<HelloMessage name="Liuliu" />, App);
20 changes: 20 additions & 0 deletions src/components/InputSearch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from "react"
import '../style/extra.css'
import "../style/input.css"

export default class InputSearch extends React.PureComponent {

getKwd (event) {
this.props.inputKwd(event.target.value)
}

render () {
return (
<div className = "verticalAbs inputDiv" >
<div className = "content horizonCenter">
<input placeholder = "Search..." type = "search" onChange = {this.getKwd.bind(this)} />
</div>
</div>
)
}
}
24 changes: 24 additions & 0 deletions src/components/NavBar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from "react"
import "../style/navBar.css"
import '../style/extra.css'

export default class NavBar extends React.PureComponent {

setChoose (name) {
this.props.setChoose(name)
}

render () {
return (
<div className = "flexBox">
{this.props.pageList.map((name) => {
return (
<div className = "item" key = {name} onClick = {this.setChoose.bind(this, name)}>
<span>{name}</span>
</div>
)
})}
</div>
)
}
}
37 changes: 37 additions & 0 deletions src/components/Product.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react'
import '../style/product.css'
import '../style/extra.css'

export default class Product extends React.PureComponent {
constructor (props) {
super(props)
this.state = {
movies : []
}
}

render () {
let { movies } = this.props


return (movies.Search ?
(<div>
{/* <h1>Movie List</h1> */}
{movies.Search.map( (movie) => {

return (
<div key = {movie.imdbID} className = "listTemplate">
<img src = {movie.Poster} width = "50px" height = "70px" alt = {movie.Title}/>
<strong className = "verticalCenter">
<a className = "linkNoUnderLine" href = {movie.Poster} target = "_blank"> {movie.Title} </a>
( {movie.Year} )
( {movie.Type} )
</strong>
</div>
)
})}
</div>) :
(<div>Waiting...</div>)
)
}
}
41 changes: 41 additions & 0 deletions src/components/Todo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react'
import '../style/todo.css'
import '../style/extra.css'

export default class Todo extends React.Component {
constructor (props) {
super(props)

this.colorChecked = "todoColorChecked"
this.colorUnchecked = "todoColorUnchecked"
}

bindCheckBox (inputId) {
const input = document.getElementById(inputId)
input.checked = !input.checked
}
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

會將 input.checked 這個部分,直接從外部帶進來,變成

this.state.checked

處理的時候直接就可以進行

this.setState({
  checked: !checked
})

底下的 checkbox checked 就可以跟著 this.state.checked 的數值直接輸出即可,就不用使用 getElementBy ...

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

checked

如果是 list 這種動態產生的 checkbox,如何用這個方法來改寫呢?
我想到的方法要根據 list id 建立對應的 state 才能做,不知道有什麼更好的方法嗎?


render() {
const {todos} = this.props

return (
<div>
{/* <h1 className = "textCenter">Todo List</h1> */}
<ol className = "padLeft-5 padRight-5">
{todos.map( (todo) => {
const todoInputId = `todo_${todo.id}`
let checked = false
if (todo.completed) checked = true

return (
<li key = {todoInputId} className = "todoTemplate cursorPoint hoverZoom" onClick = {this.bindCheckBox.bind(this, todoInputId)}>
{todo.title}
<input id = {todoInputId} className = "checkBoxPosition" type="checkbox" defaultChecked = {checked} />
</li>
)
} )}
</ol>
</div>
);
}
}
63 changes: 63 additions & 0 deletions src/style/extra.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
.verticalCenterFlex {
display: flex;
justify-content: center;
}
.verticalCenterFlex .content {
align-self: center;
}

.verticalAbs {
position : relative;
margin : auto;
}
.verticalAbs .content {
position : absolute;
top : 50%;
left : 50%;
transform : translate(-50%, -50%);

width : 50%;
height : 100%;
}

.verticalCenter {
margin-left : 3%;
position : absolute;
top : 50%;
transform : translate(0, -50%);
}


.horizonCenter {
position : absolute;
left : 50%;
transform : translate(-50%, 0);
}

.linkNoUnderLine {
color : #035daf;
text-decoration: none;
}

.linkNoUnderLine:hover {
color : red;
}
.listTemplate:hover {
zoom : 1.5;
}

.textCenter {
text-align : center;
}
.padLeft-5 {
padding-left : 5%;
}
.padRight-5 {
padding-right : 5%;
}
.cursorPoint {
cursor : pointer;
}
.hoverZoom:hover {
zoom : 1.5;
}
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

這邊用到了些 transform, 也不是不好不過如果只是要拿來做定位使用的話, transform 會使用到不少效能,盡量在如果是要對應座標,應該在父結點上面設定上去 position: relative;

27 changes: 27 additions & 0 deletions src/style/input.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
input[type = "search"] {
border-radius : 10px;
width : 100%;
height : 100%;
border : 2px solid #bdbdbd;
outline : none;
font-size: 150%;
padding-left:3%;
}
input[type = "search"]::-webkit-input-placeholder {
color : #bcbcbc;
padding : 0 0 0 1%;
}
input[type = "search"]::-webkit-search-cancel-button {
/* -webkit-appearance: none; */

background-color: #dedede;
margin : 0 1% 0 0;
zoom: 1.5;
cursor: pointer;
}

.inputDiv {
height: 40px;

margin : 0 0 2% 0;
}
33 changes: 33 additions & 0 deletions src/style/navBar.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
.flexBox {
display : flex;
flex-direction: row;
flex-wrap: wrap;

background-color: #f9f10baf;
border: 3px solid #123456;
border-radius: 15px;

margin : 0 0 3% 0;
/* padding: 0 5% 0 5%; */
}
.item {
width: 19.8%;
height: 100%;
text-align: center;
line-height: 50px;
font-size: 20px;
border-right: 2px solid #f9ae0ba7;
border-bottom: 2px solid #f9ae0ba7;
border-radius : 13px;

justify-content: flex-start;
align-items: center;

cursor: pointer;
}
.item:hover {
transform: scale(1.05, 1.2);

background-color: #f9ae0bd4;
font-size: 26px;
}
Loading