W kwietniu opublikowałem 4 wpisy :
React :
Do czego służy useReducer?
Obsługa formularzy
Inne :
Blog: Podsumowanie drugiego roku
NodeJS :
Skąd pobrać wersję dla CHROMIUM_REVISION?
Przeczytałem jedną książkę:
Miasto w chmurach - Anthony Doerr
Przesłuchałem trzy audiobooki:
Andromeda - Therese Bohman
Harda - Elżbieta Cherezińska
Hyperfocus - Chris Bailey
Jak obsługiwać formularze?
Obsługa formularzy w React jest prosta. Istnieją oczywiście biblioteki do przetwarzania danych z formularzy. W tym wpisie podam przykłady, jak ogarnąć formularz bez dodatkowej biblioteki.
Przykłady
Przykład 1 - Pobieranie wartości
import React from 'react' ;
const App = () => {
return (
<>
<label htmlFor ="name" > Name:</label >
<input type ="text" id ="name" name ="name" onChange ={(e) => console.log(e.target.value)}/>
</>
);
}
Pierwszy przykład pokazuje, jak pobrać dane z danej kontrolki. Żeby, to zrobić należy podpiąć się pod zdarzenie onChange i przekazać funkcję, która pobierze dane.
Przykład 2 - Pobieranie wartości jeszcze raz
import React, { useState } from 'react' ;
const initFormState = {
name : '' ,
javascript : false ,
java : false ,
swift : false ,
}
const App = () => {
const [formState, setFormState] = useState(initFormState);
const onChangeHandler = e => {
const value = e.target.type === 'checkbox' ? e.target.checked : e.target.value;
setFormState({
...formState,
[e.target.name]: value
})
};
const onSubmitHandler = e => {
e.preventDefault();
console .log('formState: ' , formState)
}
return (
<>
<form onSubmit ={onSubmitHandler} >
<label htmlFor ="name" > Name:</label >
<input type ="text" id ="name" name ="name" onChange ={onChangeHandler} value ={formState.name} />
<fieldset >
<legend > Select preferred programming languages</legend >
<input type ="checkbox" id ="javascript" name ="javascript" onChange ={onChangeHandler} checked ={formState.javascript}/ >
<label htmlFor ="javascript" > JavaScript</label >
<input type ="checkbox" id ="java" name ="java" onChange ={onChangeHandler} checked ={formState.java}/ >
<label htmlFor ="java" > Java</label >
<input type ="checkbox" id ="swift" name ="swift" onChange ={onChangeHandler} checked ={formState.swift}/ >
<label htmlFor ="swift" > Swift</label >
</fieldset >
<div >
<button type ="submit" > Send</button >
</div >
</form >
</>
);
}
Można napisać uniwersalną funkcję, która pobierze dane z całego formularza. Spójrz na funkcję onChangeHandler .
Za pomocą linijki kodu:
e.target.value
Możesz pobrać dane prawie ze wszystkich kontrolek. Prawie. Wyjątkiem jest kontrolka typu checkbox . Jeśli masz do czynienia z checkbox użyj:
e.target.checked
Kolejny fragment kodu:
setFormState({
...formState,
[e.target.name]: value
})
Odpowiedzialny jest za zaktualizowanie stanu formularza. Żeby to zadziałało, musisz nadać każdej kontrolce formularza nazwę za pomocą atrybutu: name .
Dzięki tak napisanej funkcji onChangeHandler możesz pobrać dane z całego formularza!
Przykład 3 - Wypełnianie formularza danymi
Poniżej przykład jak wypełnić formularz danymi lub go zresetować.
import React, { useState } from 'react' ;
const initFormState = {
name : '' ,
javascript : false ,
java : false ,
swift : false ,
color : '' ,
transport : ''
}
const Form = ({onSubmit, data} ) => {
const [formState, setFormState] = useState(initFormState);
useEffect(() => {
setFormState(data);
}, [data]);
const onChangeHandler = e => {
const value = e.target.type === 'checkbox' ? e.target.checked : e.target.value;
setFormState({
...formState,
[e.target.name]: value
})
};
const onSubmitHandler = e => {
e.preventDefault();
onSubmit(formState);
}
return (
<>
<form onSubmit ={onSubmitHandler} >
<label htmlFor ="name" > Name:</label >
<input type ="text" id ="name" name ="name" onChange ={onChangeHandler} value ={formState.name} />
<fieldset >
<legend > Select preferred programming languages</legend >
<input type ="checkbox" id ="javascript" name ="javascript" onChange ={onChangeHandler} checked ={formState.javascript}/ >
<label htmlFor ="javascript" > JavaScript</label >
<input type ="checkbox" id ="java" name ="java" onChange ={onChangeHandler} checked ={formState.java}/ >
<label htmlFor ="java" > Java</label >
<input type ="checkbox" id ="swift" name ="swift" onChange ={onChangeHandler} checked ={formState.swift}/ >
<label htmlFor ="swift" > Swift</label >
</fieldset >
<label htmlFor ="color" > Select your favorite color</label >
<select id ="color" name ="color" onChange ={onChangeHandler} value ={formState.color} >
<option > None selected</option >
<option value ="red" > Red</option >
<option value ="green" > Green</option >
<option value ="blue" > Blue</option >
</select >
<fieldset >
<legend > Transport</legend >
<input type ="radio" id ="bike" name ="transport" value ="bike" onChange ={onChangeHandler} checked ={formState.transport === 'bike' } />
<label htmlFor ="bike" > Bike</label >
<input type ="radio" id ="car" name ="transport" value ="car" onChange ={onChangeHandler} checked ={formState.transport === 'car' } />
<label htmlFor ="car" > Car</label >
<input type ="radio" id ="train" name ="transport" value ="train" onChange ={onChangeHandler} checked ={formState.transport === 'train' } />
<label htmlFor ="train" > Train</label >
</fieldset >
<div >
<button type ="submit" > Send</button >
</div >
</form >
</>
);
}
const preparedFormState = {
name : 'Jan Kowalski' ,
javascript : false ,
java : false ,
swift : true ,
color : 'green' ,
transport : 'bike'
}
const App = () => {
const [data, setData] = useState(initFormState);
const onSubmitHandler = formState => {
console .log('formState: ' , formState)
}
const onLoadData = () => {
setData(preparedFormState);
}
const onResetForm = () => {
setData(initFormState);
}
return (
<>
<Form data ={data} onSubmit ={onSubmitHandler} />
<button onClick ={onLoadData} > Load data</button >
<button onClick ={onResetForm} > Reset form</button >
</>
);
}
Jak zainstalować konkretną wersję?
Biblioteka node-chromium pozwala na zainstalowanie konkretnej wersji Chromium .
Można to zrobić tak:
export NODE_CHROMIUM_REVISION=1129607
lub stworzyć plik .npmrc i dodać:
node_chromium_revision=1129607
Tylko skąd pobrać dokładną rewizję?
Skąd pobrać CHROMIUM_REVISION?
Znalazłem dwa źródła:
Pierwsza strona pozwala na wyszukiwanie na podstawie wersji przeglądarki, ale też rewizji:
https://vikyd.github.io/download-chromium-history-version/#/
Druga wyświetla datę wypuszczenia Chromium + rewizję:
https://registry.npmmirror.com/binary.html?path=chromium-browser-snapshots/
Czym jest useReducer?
useReducer to hook , który służy do rozdzielenia logiki zarządzania stanem a renderowaniem. Jest to szczególnie przydatne, gdy stan komponentu jest bardziej złożony niż proste typy takie jak: string czy number .
Na przykład tablica elementów. Manipulowanie danymi jak: dodawanie, edytowanie i kasowanie sprawia, że komponent coraz bardziej się rozrasta. Dzięki useReducer można przenieść całą logikę zarządzania stanem do jednego miejsca.
Podobny jest do useState . useReducer powinno się używać do zarządzania stanem, który jest bardziej złożony niż proste typy.
Składnia useReducer
Użycie useReducer jest bardziej złożone niż useState . Przyjmuje dwa parametry:
const [state, dispatch] = useReducer(reducer, initialState)
Pierwszy parametr to funkcja, która będzie zarządzać stanem. To tam znajduje się cała logika odpowiedzialna za przetwarzanie danych. Drugi argument to wartość, jaką ma mieć domyślnie nasz stan.
useReducer zwraca tablicę z dwoma elementami. Pierwszy: state zawiera aktualny stan. Drugi: dispatch to funkcja, która służy do komunikacji ze stanem. Dzięki niej informujemy, jak stan powinien zostać zaktualizowany.
Jak wspomniałem do useReducer w pierwszym parametrze przekazujemy funkcję zarządzającą stanem. Przyjmuje ona dwa parametry:
function reducer (state, action )
state to aktualny stan. action to obiekt, który zawiera informacje, jak stan ma zostać zaktualizowany.
Przykłady
Przykład 1
import React, { useReducer } from 'react' ;
const ACTIONS = {
INCREMENT : 'increment' ,
DECREMENT : 'decrement' ,
RESET : 'reset'
}
const initialState = {
counter : 0
}
function reducer (state, action ) {
switch (action.type) {
case ACTIONS.INCREMENT:
return {
counter : state.counter + 1
};
case ACTIONS.DECREMENT:
return {
counter : state.counter - 1
};
case ACTIONS.RESET:
return {
counter : 0
};
default :
throw Error ('Reducer: Unknown action!' );
}
}
const App = () => {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
<div >
<h1 > {state.counter}</h1 >
</div >
<div >
<button onClick ={() => {
dispatch({ type: ACTIONS.INCREMENT })
}}>Increment</button >
<button onClick ={() => {
dispatch({ type: ACTIONS.DECREMENT })
}}>Decrement</button >
<button onClick ={() => {
dispatch({ type: ACTIONS.RESET })
}}>Reset</button >
</div >
</>
);
}
Przykład 2
import React, { useState, useReducer } from 'react' ;
const ACTIONS = {
ADD : 'add' ,
REMOVE : 'remove' ,
}
function reducer (state, action ) {
switch (action.type) {
case ACTIONS.ADD:
return [...state, action.payload.item];
case ACTIONS.REMOVE:
return state.filter((item ) => item.id !== action.payload.id);
default :
throw Error ('Reducer: Unknown action!' );
}
}
const ItemList = ({ id, title, dispatch } ) => {
return (
<>
<strong > {title}</strong >
<button onClick ={() => {
dispatch({ type: ACTIONS.REMOVE, payload: { id }, })
}}>Remove</button >
</>
)
}
function newItem (title ) {
return {
title,
id : Date .now()
}
}
const App = () => {
const [title, setTitle] = useState('' );
const [state, dispatch] = useReducer(reducer, []);
return (
<>
<div >
<input type ="text" value ={title} onChange ={(e) => setTitle(e.target.value)} />
<button onClick ={() => {
dispatch({
type: ACTIONS.ADD,
payload: {
item: newItem(title)
}
});
setTitle('');
}}>Add</button >
</div >
<div >
<ul >
{state.map((item) => {
return <li key ={item.id} > <ItemList id ={item.id} title ={item.title} dispatch ={dispatch} /> </li >
})}
</ul >
</div >
</>
);
}
Mija drugi rok działalności mojego bloga .
W ciągu 12 miesięcy opublikowałem 92 wpisy .
Dodałem nowy dział: Demo .
Opublikowałem także 17 komiksów .
Nowsze wpisy
Poprzednie wpisy