5-5. FavoriteListContainer 만들기

import FavoriteList from '../components/FavoriteList';
import { connect } from 'react-redux';

export default connect(
    (state) => ({
        contacts: state.contacts
    })
)(FavoriteList);

이번 컴포넌트는 더더욱 쉽습니다. 연결 해 줄 액션이 없으니 데이터만 넣어주면 됩니다.

하지만, 이제 우리 컴포넌트가 일반 객체가 아닌 immutable 객체들을 다루게 되었으니, 일부 컴포넌트들을 수정해주어야합니다.

FavoriteList 컴포넌트 수정하기

일반 객체가 아닌, MapList 를 다루니까 이에 맞춰서 수정을 해주겠습니다.

propTypesreact-immutable-proptypes 를 사용해서 설정을 해주고,

필터링을 하는과정과, key 를 설정하는 부분에서 .get() 을 통하여 값을 가져오도록 설정하세요.

src/components/FavoriteList

import React from 'react';
import styled from 'styled-components';
import FavoriteItem from './FavoriteItem';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';

const Wrapper = styled.div`
    /* 레이아웃 */
    position: relative; /* 자식 컴포넌트의 크기를 이 컴포넌트의 50% 로 설정하기 위함 */
    display: flex;
    flex-wrap: wrap; /* 공간이 부족하면 다음 줄에 보여줌 */
`;

const FavoriteList = ({contacts}) => {
    const favoriteList = contacts
                        .filter( // 즐겨찾기 필터링
                            contact => contact.get('favorite')
                        ).map(
                            contact => (
                                <FavoriteItem 
                                    key={contact.get('id')} 
                                    contact={contact}
                                />
                            )
                        );

    return (
        <Wrapper>
            {favoriteList}
        </Wrapper>
    );
};

FavoriteList.propTypes = {
    contacts: ImmutablePropTypes.listOf(
        ImmutablePropTypes.mapContains({
            id: PropTypes.string,
            name: PropTypes.string,
            phone: PropTypes.string,
            color: PropTypes.string,
            favorite: PropTypes.bool
        })
    )
};

export default FavoriteList;

propTypes 를 설정 할 때, ListImmutablePropTypes.listOf() 를 사용하고, MapImmutablePropTypes.mapContains() 를 사용합니다.

FavoriteItem 수정하기

FavoriteItem 컴포넌트도 조금 수정해주어야합니다. propTypes 를 수정하고, 또, contact 를 렌더링 하는 과정에서 contact: { name, phone, color } 문법이 먹히지 않으니 이를 다음과 같이 수정하세요.

src/components/FavoriteItem.js

import React from 'react';
import styled from 'styled-components';
import PropTypes from 'prop-types';
import PersonIcon from 'react-icons/lib/md/person';
import ImmutablePropTypes from 'react-immutable-proptypes';

/* style 컴포넌트 생략 */

const FavoriteItem = ({contact}) => {
    const { color, name, phone } = contact.toJS();
    return (
        <Wrapper>
            <Box color={color}>
                <ThumbnailContainer>
                    <PersonIcon/>
                </ThumbnailContainer>
                <Info>
                    <Name>{name}</Name>
                    <Phone>{phone}</Phone>
                </Info>
            </Box>
        </Wrapper>
    )
};

FavoriteItem.propTypes = {
    contact: ImmutablePropTypes.mapContains({
        id: PropTypes.string,
        name: PropTypes.string,
        phone: PropTypes.string,
        color: PropTypes.string,
        favorite: PropTypes.bool
    })
};
export default FavoriteItem;

일반 Map 인스턴스는 비구조화 할당이 되지 않으니, toJS() 를 한 다음에 비구조화 할당을 하였습니다.

App 에서 불러와서 사용하기

이제 FavoriteListContainerApp 컴포넌트에서 불러와서 렌더링하세요.

src/App.js

import Header from './components/Header';
import Container from './components/Container';
import { connect } from 'react-redux'

import ViewSelectorContainer from './containers/ViewSelectorContainer';
import InputContainer from './containers/InputContainer';
import FavoriteListContainer from './containers/FavoriteListContainer';

class App extends Component {
    render() {
        // 레퍼런스 준비
        const { view } = this.props;

        return (
            <div>
                <Header/>
                <ViewSelectorContainer/>

                {/* view 값에 따라 다른 컨테이너를 보여준다 */}
                <Container visible={view==='favorite'}>
                    <FavoriteListContainer/>
                </Container>
                <Container visible={view==='list'}>
                    <InputContainer/>
                    {/* ContactListContainer */}
                </Container>

                {/* ContactModalContainer */}
                {/* FloatingButtonContainer */}
            </div>
        );
    }
}

export default connect(
    (state) => ({
        view: state.base.get('view')
    })
)(App);

results matching ""

    No results matching ""