Nihilist Postmodern Mistake

    react-containers
    TypeScript icon, indicating that this package has built-in type declarations

    16.0.5 • Public • Published

    react-containers

    Build Statuscoverage report npm version

    Usage

        npm install --save react-containers
    
    import {
        Center
        Render
        LeftRightSection,
        InlineItems,
        findChild,
        MappingOver,
        WrappingChildren
    } from 'react-containers'
     

    Motivation

    The following components can be used to write a more declarative React components. These components combined with others like styled-components for example provides with a much more easier to read source code.

    Take for example the source code of a component below

     
    render() {
     
        return (
            <div className={css.container}>
                { this.state.items.map( (item,index) => {
                    return (
                        <Item 
                            onClick={this.onItemClicked}
                            key={index} 
                            data={item}>
                            { item.name }
                        </Item>
                    )
                })}
            </div>
     
        )
     
    }
     

    Although the code above works, it is much easier to read something like the one below

    ...
    renderItem = (item, index) => (
        <Item 
            onClick={this.onItemClicked}
            key={index} 
            data={item}>
            { item.name }
        </Item>
    )
     
    render() {
     
        return (
            <Container>
                <MappingOver collection={this.state.items}>
                    { this.renderItem }
                </MappingOver>
            </Container>
     
        )
     
    }
     
    ...
     

    Components

    Left and Right Sections

    Provide a left and/or right section. The first element is the left section while the second element is the right section. Note that if you only require a right section then make sure that the first element is not empty.

    Left And Right Section

    import { LeftRightSection, Center } from 'react-containers';
     
    //left and right
    <LeftRightSection>                   
        <ProductTitle>Cool Product</ProductTitle>
        <Center><Menus/></Center>
    </LeftRightSection>     
     

    Right Side Only

    import { LeftRightSection, Center } from 'react-containers';
     
    <LeftRightSection>
        <div/>
        <Center><Menus/></Center>
    </LeftRightSection>
     

    InlineItems

    Renders item inline with a spacing. Similar to something like what flex will do by default.

    render() {
        return (
            <div style={{display: 'flex'}}>
                <div className={'spacer'}><MySpecialElement/></div>
                <div className={'spacer'}><MyOtherElement/></div>
            </div>
        )
    }

    can be replaced with something like

     
    render() {
        return (
            <InlineItems>
                <Container><MySpecialElement/></Container>
                <Container><MyOtherElement/></Container>
            </InlineItems>
        )
    }
     

    To prevent repetition, you can do something like

     
    render() {
        return (
            <InlineItems container={Container}>
                <MySpecialElement/>
                <MyOtherElement/>
            </InlineItems>
        )
    }
     

    Center

    This container will center horizontally and vertically a component rendered inside.

     
    import { Center } from 'react-containers'
     
    <div style={{width: 250, height: 250}}>
        <Center><SomeComponent /></Center>
    </div>
     

    You can also choose to specify the dimension of the container...

     
    import { Center } from 'react-containers'
     
     
    <Center style={{width: 250, height: 250}}>
        <SomeComponent />
    </Center>
     
     

    Render if

    Will call the function child if ifTrue attribute is true. Note that the child can be an element or a function but it is advisable to pass a function if you dont want the element created in cases where ifTrue attribute is initially false.

    <RenderIf expr={this.props.shouldRender}>
       { (props) => <MyComponent {...props} /> };
    </RenderIf>
     
    //below is the same but the function child is not created on subsequent render
     
    class MyComponent extends React.Component {
     
        showToggledView = () => {
            return <ToggledView {...this.props.toggledProps }/>;
        }
     
        render() {
            return (
                <div>
                    <SomeComponent />
                    <Render ifTrue={this.props.isToggled}>
                        { this.showToggledView }
                    </RenderIf>
                </div>
            )
        }
     
    }

    MappingOver

    Map over a given collection specifying the function that returns the component that maps over the element. Make sure your renderer adds a key

     
    import { MappingOver } from 'react-containers'
     
    ...
    renderItem = (item, index) => (
        <Item 
            onClick={this.onItemClicked}
            key={index} 
            data={item}>
            { item.name }
        </Item>
    )
     
    render() {
     
        return (
            <Container>
                <MappingOver collection={this.state.items}>
                    { this.renderItem }
                </MappingOver>
            </Container>
     
        )
     
    }
     
    ...

    The component can also use an functional component as the child. MappingOver will automatically create a React Element.

     
    const Item = (props) => {
        const { element, index, collection, data } = props
     
        return (
            <div key={index}>{index}</div>
        )
    }
     
    // from another component
     
    return (
        <Container>
            <MappingOver collection={this.state.items}>
                { Item }
            </MappingOver>
        </Container>
     
    )
     

    findChild

    findChild is particularly useful for finding elements when you want to create tagger elements. Consider the following component

     
    // MyComponent.js
     
    export const Header = (props) => {
        throw new Error('should not render')
    }
    export const Body = (props) => {
        throw new Error('should not render')
    }
    export const Title = (props) => {
        throw new Error('should not render')
    }
     
    export const App = (props) => {
        const titleElement = findChild(Title, props)
        const headerElement = findChild(Header, props)
        const bodyElement = findChild(Body, props)
        
        return (
            <Container>
                <LeftRightSection>
                    <TitleContainer>{ titleElement.props.children }</TitleElement>
                    <MainHeaderContainer>{ headerElement.props.children }</TitleElement>
                </LeftRightSection>
                <BodyContainer>
                    { bodyElement.props.children }
                </BodyContainer>
            </Container>
        )
    }
     

    Now your users will just create MyApp with something like

     
        import { Header, Body, Title, App } from 'myawesomeapp'
     
        render() {
            return (
                <App>
                    <Title><Strong>My App Here</Strong></Title>
                    <Header><Menus /></Header>
                    <Body><MyAppContent></Body>                
                </App>
            )
        }
     

    This makes for a far better declarative way of using your component as they dont need to worry about structuring it but only declaring sections

    Contributing

    You can submit a propasal if you have a container you wanted to contribute.

    Install

    npm i react-containers

    DownloadsWeekly Downloads

    13

    Version

    16.0.5

    License

    MIT

    Unpacked Size

    58.3 kB

    Total Files

    56

    Last publish

    Collaborators

    • wmira