Skip to content

Instantly share code, notes, and snippets.

@ywwwtseng
Last active November 25, 2019 12:22
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 ywwwtseng/45011248a9093e174567a7db6ad20352 to your computer and use it in GitHub Desktop.
Save ywwwtseng/45011248a9093e174567a7db6ad20352 to your computer and use it in GitHub Desktop.

React Hooks

什麼是 React Hooks?

React Hooks 是 16.7 版推出的功能,使用 React Hooks 讓我們可以減少使用 Class Components 去建構我們的 React 應用程式。

useState

使用 useState 可以讓我們的 Functional Components 具備狀態,userState 的 setter 比 setState 更具可讀性。

function App() {
	const [count, setCount] = useState(0);
	const incrementCount = () => setCount(prevCount => prevCount + 1);
	
	
	return (
		<button onClick={incrementCount}>{count}</button>
	);
}

useEffect

用來處理副作用(可以理解為一切除結果計算之外發生的事情,ex:發送一個http 請求)

function App() {
	const [mousePosition, setMousePosition] = useState({ x: null, y: null });

	useEffect(() => {
		document.title = 'hi title';
	}, []);
	
	useEffect(() => {
		window.addEventListener('mousemove', handleMouseMove);
		
		return () => {
			window.removeEventListener('mousemove', handleMouseMove);
		}
	}, []);
	
	const = handleMouseMove = (event) => {
		setMousePosition({ x: pageX, y: pageY });
	};
	
	...
}

navigator.onLine Example

function App() {
	const [onLine, setOnLine] = useState(navigator.onLine);
	
	useState(() => {
		window.addEventListener('online', handleOnLine);
		window.addEventListener('offline', handleOffLine);
		
		return () => {
			window.removeEventListener('online', handleOnLine);
			window.removeEventListener('offline', handleOffLine);
		};
	}, []);
	
	const handleOnLine = () => {
		setOnLine(true);
	};
	
	const handleOffLine = () => {
		setOnLine(false);
	};
}

navigator.geolocation Example

const initialLocationState = {
	latitude: null,
	langitude: null,
	speed: null,
};

function App() {
	const [location, setLocation] = useState(initialLocationState);
	let mounted = true;
	
	
	useEffect(() => {
		navigator.geolocation.getCurrentPosition(handleGeolocation);
		const watchId = navigator.geolocation.watchPosition(handleGeolocation);
		
		return () => {
			mounted = false;
			navigator.geolocation.clearWatch(watchId);
		}
	}, []);
	
	const handleGeolocation = (event) => {
		if (mounted) {
			setLocation({
				latitude: event.coords.latitude,
				langitude: event.coords.langitude,
				speed: event.coords.speed,
			});
		}
	};
	
}

login Example

function App() {
	const [username, setUsername] = useState('');
	const [password, setPassword] = useState('');
	
	const handleSubmit = (event) => {
		event.preventDefault();
		const userData = {
			username,
			password,
		};
		
		// do something
		
		setUsername('');
		setPassword('');
	};
	
	return (
		<form onSubmit={handleSubmit}>
			<input 
				placeholder="Username"  
				value={username} 
				onchange={(event) => setUsername(event.target.value)}
			/>
			<input 
				placeholder="Password"  
				value={password} 
				onchange={(event) => setPassword(event.target.value)}
			/>
			<button type="submit">Login</button>
		</form>
	);
}

form Example

const initialFormState = {
	username: '',
	email: '',
	password: '',
};

function App() {
	const [form, setForm] = usestate(initialFormState);
	
	const handleChange = (event) => {
		setForm({
			...form,
			[event.target.name]: event.target.value,
		});
	};
	
	const handleSubmit = (event) => {
		event.preventDefault();
		
		...
		
		setForm(initialFormState);
	};
	
	...
}

fetchData

function App() {
	const [query, setQuery] = useState('');
	const [user, setUser] = useState(null);
	const [err,] = useState(null);
	
	useEffect(() => {
		fetchUser(query);
	}, [query])
	
	const fetchUser = async (query) => {
		try {
			const response = await axios.get('endpoint', { params: query });
			setUser(response.data);
		}
		catch(err) {
			setErr(err);
		}
		
	};

}

Context

const UserContext = React.createContext();

function App() {
	const value = useContext(UserContext);

	return (
		<div>Hi, {value}</div>
	);
}

ReactDOM.render(
	<UserContext.Provider value={'william'}>
		<App/>
	</UserContext.Provider>,
	document.getElementById('root')
);

replace redux

// context.js
export default React.createContext({
	todos: [
		{ id: 1, text: 'eat breakfast', complete: false },
		{ id: 2, text: 'reading', complete: false },
		{ id: 3, text: 'sleep', complete: false },
	],
	currentTodo: {}
});

// reducer.js
export default reducer(state, action) {
	switch(action.type) {
		case 'TOGGLE_TODO':
			return {
				...state,
				todos: state.todos.map(todo => 
					todo.id === action.payload.id
						? { ...todo, complete: !todo.complete }
						: todo
			};
			
		case 'REMOVE_TODO':
			return {
				...state,
				todos: state.todos.filter(todo => todo.id === action.payload.id)
			};
			
		
		
		default:
			return state;
	}
}

// index.js
import Context from './context';
import reducer from './reducer';

const App = () => {
	const initialState = useContext(context);
	const [state, dispatch] = useReducer(initialState, reducer);
	
	return (
		<Context.Provider value={{ state, dispatch }}>
			<TodoList />
		</Context.Provider>
	);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment