Skip to content

Instantly share code, notes, and snippets.

@pgbovine
Created February 10, 2014 04:25
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save pgbovine/8910348 to your computer and use it in GitHub Desktop.
JavaScript Gist for 6.813 Lecture 2
var result = document.evaluate("//text()", document.body, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null) ;for (var i = 0; i < result.snapshotLength; ++i) {var node = result.snapshotItem(i);if ((node.textContent+"").match(/\w/)&&node.parentNode.nodeName != "STYLE") {node.textContent = node.textContent.replace(/[A-Z0-9]/g, "X").replace(/[a-z]/g, "x");}}void 0
@lingxiao
Copy link

lingxiao commented Jul 29, 2018

import React, {Component} from 'react';
import { FlatList } from "react-native";
import Text from './Text';

export default class SpiceFlatList extends Component {

    constructor(props){
        super(props);
        this.state = {
              loading    : false
            , data       : []
            , ids        : []       // store unique ids to make sure only new items are loaded
            , refreshing : false
            , mounted    : false
        }
    }

    async componentDidMount(){
        this.setState({ mounted : true }, () => this.loadData());
    }


    componentWillUnmount(){
        this.setState({ mounted : false })
    }


    /************************************************************************
        Load data
    ************************************************************************/

    loadData = async () => {

        this.setState({ loading: true });

        // get data 
        const res = this.props.getData 
            ? await this.props.getData()
            : await false

        // if failed, then finish loading
        if (!res)
            this.setState({ loading: false, refreshing : false });

        /**
            @Use: append unique elements to list
        */
        if (this.state.mounted) {

            const { data, ids } = await this.loadUniques(res);

            this.setState({
                  data      : data
                , ids       : ids
                , loading   : false
                , refreshing: false
            });

            // flip parent component feedloaded boolean flag
            if (this.props.screenProps && this.props.screenProps.feedLoaded)
                this.props.screenProps.feedLoaded();

        }
    }
    

    /**
        @Use: combine new data with old data so that only unique values remain
    */
    loadUniques = async res => {

        const xs  = this.state.data;       
        const ids = this.state.ids;
        const ys  = res.results;

        if ( !ys )
            return { data: xs, ids : ids }

        if ( this.state.refreshing || !xs) {
            return { data : ys, ids : ys.map(y => this.props.keyExtractor(y))}
        }

        // console.log('thiscase: ', ys)

        // append unique elements
        ys.forEach(y => {


            const uid = this.props.keyExtractor(y);

            if (ids.indexOf(uid) === -1) {
                xs.push(y)
                ids.push(uid)
            }
        });

        return { data : xs, ids : ids }
    }


    /************************************************************************
        control flow
    ************************************************************************/

    // this is appending to elements.. when it should not be
    onRefresh = () => 
        this.setState({ refreshing : true }, () => this.loadData())

    loadMore = () => 
        this.loadData()

    /************************************************************************
        Render
    ************************************************************************/

    render() {

        const list = (
            <FlatList
                removeClippedSubviews = {true}
                horizontal            = {this.props.horizontal}
                showsHorizontalScrollIndicator = {false}

                keyExtractor        = {this.props.keyExtractor}
                ListHeaderComponent = {this.props.renderHeader}
                renderItem          = {this.props.renderItem  }

                data                = {this.state.data      }
 
                refreshing          = {this.state.refreshing}
                onRefresh           = {this.onRefresh       }
                onEndReached        = {this.loadMore        }
                onEndThreshold      = {2}
                {...this.props}
            />
        )
            
        return this.props.getData ? list : null;
    }
}    

@lingxiao
Copy link

lingxiao commented Jul 29, 2018

A example use case below:

export default class OneFeed extends Component {

	GET = async () => 
		await getRecommendations(this.props.screenProps.uid);

	/**
		@right now you need to figure out the loading state render ...
	*/
	renderItem = ({ item }) => {

		if (!item)
			return null;

		const name = item.displayName 
			? item.displayName
			: '';

		const image_src = item.thumbURI 
			? { uri: item.thumbURI } 
			: blank;

		const image = <Thumbnail source={image_src} />

        return (
        	<TouchableOpacity onPress={() => this.props.onFollow(name)} >
				<CardItem >
	                <Body style={whoToFollow.box}>
	                    {image}
	                    <Text label={name} style={whoToFollow.caption}/>
	                </Body>
	           </CardItem>
	        </TouchableOpacity>
	    )
	}


	render = () =>
        <SpiceFlatList
			horizontal   = {true}
            getData      = {this.GET          }
            renderItem   = {this.renderItem   }
            keyExtractor = {item => item.uid  }
            {...this.props}
        />

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment