Skip to content

Commit

Permalink
Merge pull request #11 from tegraoss/feature/use-plug
Browse files Browse the repository at this point in the history
UseStream Custom Hook
  • Loading branch information
Vitormdias committed Jun 15, 2019
2 parents 4e2da40 + fbf56d8 commit 8b8685f
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 3 deletions.
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,34 @@ When you call `updateState`, your new data will be merged with the current data

<hr />

<p align="center">
<img src="assets/luffiejs-usestream.png">
</p>

The other side of the coin is the UsePlug Hook. This way you can Plug your component into your newly created Store and at each change, the store data update your component's state.

```javascript
const TestComponent = (props) => {
const { name } = props;
const state = usePlug(state$)
return (
<div>
<h1 data-testid="name">{name}</h1>
<p data-testid="total">Total: {total}</p>
<p data-testid="changed">The store was{changed ? '' : `n't`} changed.</p>
</div>
)
}
```

<hr />

<p align="center">
<img src="assets/luffiejs-plug.png">
</p>

The other side of the coin is the Plug HOC. This way you can Plug your component into your newly created Store and at each change, the store data will be forwarded as props to your component.
**Use Luffie like this if your React doesn't support Hooks**
If you use a older version of React without Hooks, you can use the Plug HOC to connect your component with you store state following the steps described below:

**1. Create your Container**

Expand Down
40 changes: 40 additions & 0 deletions __tests__/use-stream.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as React from 'react';
import { render, cleanup, waitForElement } from 'react-testing-library';
import 'jest-dom/extend-expect'
import { setTotal10ChangedTrue, cleanStore } from '../lib/utils/example-store';
import { UsePlugTestComponent } from '../lib/utils/example-usestream';

describe('Plug', () => {
afterEach(cleanup);
afterAll(() => cleanStore())

it('Renders', async done => {
const { getByTestId } = render(<UsePlugTestComponent name="Test Testersson" />);

const nameNode = await waitForElement(() => getByTestId('name'))
const totalNode = await waitForElement(() => getByTestId('total'))
const changedNode = await waitForElement(() => getByTestId('changed'))

expect(nameNode).toHaveTextContent('Test Testersson');
expect(totalNode).toHaveTextContent('Total: 0');
expect(changedNode).toHaveTextContent(`The store wasn't changed`);
done();
})

it('Renders with new State', async done => {
setTotal10ChangedTrue();

const { getByTestId } = render(<UsePlugTestComponent name="Test Testersson" />);

const nameNode = await waitForElement(() => getByTestId('name'))
const totalNode = await waitForElement(() => getByTestId('total'))
const changedNode = await waitForElement(() => getByTestId('changed'))

expect(nameNode).toHaveTextContent('Test Testersson');
expect(totalNode).toHaveTextContent('Total: 10');
expect(changedNode).toHaveTextContent(`The store was changed`);
done();
})
})


Binary file added assets/luffiejs-usestream.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { plug } from "./plug";
import { createStore } from "./store";
import { useStream } from "./use-stream";

export {
plug,
createStore
createStore,
useStream,
}
16 changes: 16 additions & 0 deletions lib/use-stream.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { useState, useEffect } from "react";
import { Observable } from "rxjs";

export function useStream<T>(stream: Observable<T>) {
const [streamData, setStreamData] = useState<T | null>(null);

useEffect(() => {
const sub = stream.subscribe(data => setStreamData(data));

return () => {
sub.unsubscribe();
}
})

return streamData;
}
7 changes: 6 additions & 1 deletion lib/utils/example-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,15 @@ const setTotalDouble = () => updateState((state: any) => ({
total: state.total * 2
}));

const cleanStore = () => {
updateState(initialState);
}

export {
state$,
getCurrentState,
setTotal10ChangedTrue,
setTotal20,
setTotalDouble
setTotalDouble,
cleanStore
}
25 changes: 25 additions & 0 deletions lib/utils/example-usestream.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import * as React from 'react';

import { useStream } from '../use-stream';
import { state$ } from './example-store';

interface IProp {
name: string;
}

const UsePlugTestComponent = (props: IProp) => {
const state = useStream(state$);
if(!state) return null;

return (
<div>
<h1 data-testid="name">{props.name}</h1>
<p data-testid="total">Total: {state.total}</p>
<p data-testid="changed">The store was{state.changed ? '' : `n't`} changed.</p>
</div>
)
}

export {
UsePlugTestComponent,
}

0 comments on commit 8b8685f

Please sign in to comment.