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