背景
上周末在家没啥事, 想写点东西,一时不知道写什么好。 然后就想起来一个去了Airbnb
的同学, 说Airbnb 的面试风格是以实操为主,她面了8轮, 轮轮都是写代码(2018年), 令人十分害怕。
代码题目都不是很难, 简单分享几道题:
然后我就看到了实现一个Todo List
。
这种题目不难, 但是灵活度很高
, 没有什么限制
条件, 你随意发挥, 可以从多方面考察候选人。
就拿这道题下手吧, 开造。
[ 文末有本文全部的源代码, 通过这个例子, 你会了解 React Context
,Hooks
的使用方式, 以及 如何使用 Golang 编写 CURD Api
]
废话不多说了,进入正题。
功能实现
首先就是新建一个项目, 不限工具, CRA
什么的都可以, 我就用了之前自己写的一个工具, 简单起了项目, 不过这些都无所谓了, 直接上代码:
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.js';
ReactDOM.render(<App />, document.getElementById('root'));
App
// App.js
import React from "react";
import { TodosProvider } from './Store'
import { TodoList } from './TodoList'
const App = () => {
return (
<TodosProvider>
<TodoList />
</TodosProvider>
);
}
export default App
Store
这里我创建了两个Context, 一个用于存储
数据, 另一个用于更新
数据。
例如:
const initialState = []
const StateContext = React.createContext(initialState)
const UpdateContext = React.createContext(null)
被 Context 包裹的组件可以取用这些传入的值。
完整代码:
// Store.js
import React from 'react'
import produce from 'immer'
// An array of todos, where a todo looks like this:
// { id: string; title: string; isCompleted: boolean }
const initialTodos = [{
id: 1,
title: "One",
isCompleted: false
}, {
id: 2,
title: "Two",
isCompleted: false
}, {
id: 3,
title: "Three",
isCompleted: false
}]
const StateContext = React.createContext(initialTodos)
const UpdateContext = React.createContext(null)
export function TodosProvider({ children }) {
const [todos, updateTodos] = React.useReducer(produce, initialTodos)
return (
<UpdateContext.Provider value={updateTodos}>
<StateContext.Provider value={todos}>
{children}
</StateContext.Provider>
</UpdateContext.Provider>
)
}
export function useTodos() {
return [React.useContext(StateContext), React.useContext(UpdateContext)]
}
Todo主体
这里的实现也很简单,我先简单做了两个小功能, 一个是完成
某一项, 一个是删除
某一项, 完整代码:
// TodoList
import React from 'react';
import { useTodos } from './Store'
export function TodoList() {
const [todos, updateTodos] = useTodos()
const deleteTodo = id => updateTodos(todos => {
const todoIdxToDelete = todos.findIndex(todo => todo.id === id)
todos.splice(todoIdxToDelete, 1)
})
const completeTodo = id => updateTodos(todos => {
todos.find(todo => todo.id === id).isCompleted = true
})
return (
<ul>
{todos.map(todo => (
<li key={todo.id} style={todo.isCompleted ? { color: 'red' } : { color: 'green' }}>
<span>{todo.title}</span>
<button onClick={() => deleteTodo(todo.id)}>Delete</button>
<button onClick={() => completeTodo(todo.id)}>Complete</button>
</li>
))}
</ul>
)
}
DEMO:
下面把新增也一起做了。
想着都已经做到这一步了, 数据一刷新就没了, 干脆存到数据库里吧, 最终的样子:
后端接口实现:
看下这几个CURD
接口是怎么写的:
Api: C
Api: U
Api: R
Api: D
代码都比较简单, 一眼就能看明白是做什么的, 就不多做解释了。
后端完整的代码在这里:
https://github.com/beMySun/go...
前端部分完整的代码在这里:
https://github.com/beMySun/re...
数据库用的 mySql, 建库, 加改表可以用这个Sequel Pro, 很方便
如果不想用这个, 也可以用命令行工具来操作。
再贴几个会用的命令吧:
show databases;
use database;
describe todos_tab;
select * from todos_tab limit 10;
加一个字段:text
加一个字段:isCompleted
最后
功能很简单, 但是做的时候需要考虑的东西还是很多的。
如果有朋友也想学习下, 可以把代码下载下来自己运行跑一下。
后端完整的代码在这里:
https://github.com/beMySun/go...
前端部分完整的代码在这里:
https://github.com/beMySun/re...
这个后端的demo 包含了完整的CURD, 是一个很好的学习demo, 希望对大家的学习有所帮助。
才疏学浅, 行文难免有纰漏。
若有错误, 欢迎指正,谢谢。
以上。
如果本文对你有帮助, 别忘了点赞呦~
参考资料:
https://learnku.com/golang/t/...
https://gorm.io/docs/update.h...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。