Rozdział za rozdziałem
Jak już wspominałem zaczynam powoli dobierać się w konkursowym projekcie Let’s Write do głównych funkcjonalności. Tym razem zabrałem się za dodawanie rozdziałów.
- Wstęp
- Kilka słów o projekcie
- Pierwsza konfiguracja środowiska
- Krótko o początkach z Reactem
- Bardzo brzydkie style
- Uruchomienie Reduxa i Routera
- Jednak Bootstrap
- Poprawki i nowości
- Początek koszmaru – formularze
- Gorzkie żale związane z walidacją
- Pierwsze, nienajlepsze spotkanie z biblioteką redux-form
- Formularze w końcu zadziałały
- Nareszcie coś związanego z główną funkcjonalnością
W tym momencie mam zrobione proste dodawanie rozdziału do opowiadania z wybranym ID. Tutaj miałem właściwie największy problem ze zmockowaniem tego z wykorzystaniem samego Reduxa. W rzeczywistej aplikacji, z dodaną warstwą backendu po prostu wysłałbym request do serwera gdzie podane by było dla jakiego opowiadania jest dodawany rozdział. W przypadku symulowania tego z poziomu Reduxa najwięcej zabawy miałem przy obsłudze listy opowiadań i rozdziałów w store. Ostatecznie reducer dla opowiadań wygląda tak:
const yourStoryReducer = function(state = initialState, action) {
switch(action.type) {
case types.NEW_STORY:
let max_id = state.stories.length > 0 ? Math.max(state.stories.map((story) => {return story.id})) : 0
action.story.id = max_id + 1
return {
...state,
stories: [...state.stories, action.story]
}
case types.NEW_CHAPTER:
return {
...state,
stories: state.stories.map(s => {
if(s.id == action.storyId) {
s.chapters = [...s.chapters, action.chapter]
}
return s
})
}
}
return state
}
O operatorze trzykropka wspominałem poprzednio dlatego zapraszam do poprzedniego wpisu. Do samej obsługi wstawiania rozdziału do konkretnego opowiadania skorzystałem z metody map() . Tworzy mi ona nową listę. Funkcja przekazana jako parametr przy standardowych zastosowaniach odpowiada za mapowanie jednej wartości na drugą. Tutaj jest to bardziej obejście problemu z wyszukaniem po ID. Nie wygląda to najlepiej ale taka konstrukcja będzie obecna tylko do czasu dodania kodu zajmującego się przetwarzaniem requestów i obsługą bazy danych. To rozwiązanie działa w ten sposób, że dla opowiadań z innym ID zwracane są po prostu te opowiadania, zaś w przypadku natrafienia na opowiadanie o przekazanym ID (funkcja przekazana do map() przetwarza każdy obiekt osobno) jest ono modyfikowane – zostaje dodany rozdział do listy rozdziałów.
Sam formularz nowego rozdziału jest raczej podobny do poprzednich:
const NewChapter = React.createClass({
render: function() {
return (
<Row>
<Col mdOffset={2} md={8}>
<Form horizontal onSubmit={this.props.handleSubmit(this.props.addChapter)} method="post">
<Field name="storyId" component={storyId =>
<input type="hidden" value={this.props.storyId} {...storyId} />} />
<Field name="title" type="text" label="Title" component={FormInput} />
<Field name="description" label="Short description" component={FormTextarea} />
<FormGroup>
<Col sm={12}>
<Button type="submit" block bsStyle="primary">
Add chapter
</Button>
</Col>
</FormGroup>
</Form>
</Col>
</Row>
)
}
})
export default reduxForm({
form: 'new-chapter-form'
})(NewChapter)
I cóż, to na tyle dzisiaj. Ten tydzień nie sprzyjał rozwojowi projektu, praca etatowa zabrała więcej czasu niż zwykle. Ale nadchodzi weekend majowy kiedy będę miał 9 dni wolnego. Wygląda to jak dobry moment na kodzenie do upadłego :D
W ostatnim czasie rodzą mi się również nowe pomysły związane z blogiem i tym co na nim mam. Liczę, że po zakończeniu konkursu „Daj Się Poznać 2017” zobaczycie co mi się urodziło w głowie.
Jak zwykle przypominam, że dodatkowe informacje zwykle możecie znaleźć na moim fanpagu na Facebooku. Zaś w miarę aktualny kod konkursowej aplikacji dostępny jest na GitHubie.



Leave a Comment