An open API service indexing awesome lists of open source software.

https://github.com/ymzuiku/signalist

Use signal in react, like solidJS, all components only render once!
https://github.com/ymzuiku/signalist

Last synced: about 2 months ago
JSON representation

Use signal in react, like solidJS, all components only render once!

Awesome Lists containing this project

README

        

# Signalist

⚠️ The package is still in the experimental stage...

⚠️ The current performance is not as good as React Fiber: [https://signalist-demo.vercel.app/](https://signalist-demo.vercel.app/)

> The meaning of the logo is that React is frozen.

> Everything in signalist is a poor imitation of solidjs applied to React.

## About Signalist

Signalist is a React library that allows for granular updates to elements at the attribute level, using the signal method to avoid full component re-renders.

Signalist focus on performance and simplicity. With Signalist, you can enjoy the benefits of using signals to manage your state, just like you would with SolidJS. This allows you to build reactive user interfaces that only re-render when necessary, improving the performance of your application.

Signalist improves performance by only updating the necessary attributes of the components, rather than re-rendering the entire component. This means that only the specific properties that need to be updated will be changed, resulting in faster and more efficient updates.

Signalist is fully compatible with the existing React ecosystem and components. You can use your favorite React libraries and tools, and still benefit from the performance improvements offered by Signalist.

## Benefits

- Signal-based state management for improved performance
- No re-renders components, only updating the necessary attributes of the components
- Compatible with the existing React ecosystem and components
- Supports SSR
- Supports Typescript
- Lightweight and easy to use

## Compatibility

Signalist is designed to be fully compatible with the existing React ecosystem and components. You can use your favorite React libraries and tools, and still benefit from the performance improvements offered by Signalist.

## Getting Started

To get started with Signalist, install it using npm:

```
npm install signalist
```

Now, you can use the `useSignal` hook to create and subscribe to signals in your components:

```tsx
import { useSignal, signalJSX } from "signalist";

function MyComponent() {
const count = useSignal(0);

console.log("render once!");

// signalJSX hooks, auto binding signal to elements
return signalJSX(


Count: {count}


count.value + 1}>Increment
,
);
}
```

### APIs

- signal: create global signal object
- computed: use function subscribe some signals
- useSignal: create signal in react component, it keep value in other react setState change.
- signalJSX: binding react JSX to signal update DOM
- If: Append or remove some element, when value signal change
- For: Use list data or list signal render a list elements
- signalStorage: signal object, auto load/save from localstorage, `signalStorage` is used in conjunction with `useInitStorage` to ensure hydration consistency during SSR.

## Usage

### Signal in props

```tsx
import { useSignal, signalJSX, Signal } from "signalist";

function PageA({ count }: { count: Signal }) {
// no rerender, only reset div element textcontent:
return signalJSX(

Count: {count}
);
}

function PageB({ count }: { count: Signal }) {
// no rerender
return signalJSX(

(count.value += 1)}>update value
);
}

function MyComponent() {
const count = useSignal(0);
// no rerender
return signalJSX(




,
);
}
```

### computed

Use `signal()` in `computed`, computed can auto subscribe signal change, and return a new value

```tsx
import { computed, useSignal, signalJSX } from "signalist";

function MyComponent() {
const count = useSignal(0);

// style is typeof Signal
const style = computed(() => ({
// text() can subscribe
// text.value only read value
fontSize: text().length + "px",
color: "#00f",
}));

return signalJSX(


count: {count}


(count.value += 1)}> add count
,
);
}
```

### signal

`signal` is a native JavaScript method that can be used anywhere, in any framework, to trigger updates directly in React. However, when using `signal` inside a React component, you should use `useSignal`, which is just a `useRef` wrapper around `signal`, to prevent signal loss caused by React's `setState`. If you're using `signalist` exclusively and have never used React's `setState`, you can even use `signal` instead of `useSignal` throughout your project.

```tsx
import { signal } from "signalist";

// Declare in Anywhere

const username = signal("user-name");

// Other page component:
function PageA() {
return signalJSX(

User name: {username}
);
}

// Other page component:
function PageB() {
return signalJSX( (username.value += e.target.value)} />);
}
```

### Effect

Sure, here's a possible README file for your GitHub repository:

`effect` is a signal subscription function that collects any `signal()` calls used within it, and re-executes the effect whenever the signals mutate. If you only want to retrieve the value of a signal without subscribing to it, you can use `signal.value`, which only reads the value without subscribing.

```jsx
import React from "react";
import { signal } from "signalist";
import Effect from "@signalist/effect";

function MyComponent(props) {
const [count, setCount] = React.useState(0);

// Subscribe to the count signal and log its value
effect(() => {
console.log(signal(count));
});

const handleClick = () => {
setCount(count + 1);
};

return (


Count: {count}


Increment

);
}
```

In this example, the `effect` function subscribes to the `count` signal and logs its value whenever it changes. Whenever the `count` state is updated, the `effect` function will re-execute and log the new value of the `count` signal.

Using `effect` can simplify the process of subscribing to signals and executing code when they mutate. It provides a simple and intuitive syntax for handling signal subscriptions, making it easier to write efficient and performant React components.

### Effect + component + global signal example:

```tsx
import { signal, effect } from "signalist";

const userInfo = signal();

// Other page component:
function PageA() {
effect(async () => {
const data = fetch("/api/user-info?name" + username()).then((v) => v.json());
userInfo.value = data;
});
return signalJSX(

User name: {username}
);
}

// Other page component:
function PageB() {
const email = computed(() => userInfo().email);

return signalJSX(


(username.value += e.target.value)} />
{email}

,
);
}
```

### If component

> Because without `re-render`, you can only do this.

The If component is a React component that serves as a replacement for the ternary operator in React. It allows you to conditionally render components based on a boolean expression, without having to resort to a ternary operator.
To use the If component, import it into your React component and use it as follows:

```ts
import { computed, useSignal, signalJSX } from "signalist";
function MyComponent() {
const show = useSignal(false);
// no rerender
return signalJSX(


(show.value = !show.value)}>Change show

ok, i maby show


,
);
}
```

### For component

> Because without `re-render`, you can only do this.

# For Component

The `For` component is a React component that serves as a replacement for the `map()` function in React. It allows you to easily render a list of components based on an array of data, without having to manually iterate over the array and return a list of components.

In this example, the `For` component is used to render a list of items based on an array of data. The `each` prop specifies the array of data to iterate over, and the children of the `For` component are a function that takes two arguments: the item from the array and its index. The function returns the component to be rendered for each item in the array.

```ts
import { computed, useSignal, signalJSX } from "signalist";
function MyComponent() {
const list = useSignal([]);
// no rerender
return signalJSX(


{
list.value = [...list.value, e.target.value];
}}
>
Change show

{(item) =>
{item}
}
,
);
}
```

#### For component props

The `For` component accepts the following props:

- `each`: An array of data to iterate over.
- `children`: A function that takes two arguments: the item from the array and its index. The function returns the element or component to be rendered for each item in the array.

### With react state, useEffect

> Slower than React by default, because every time `setState` is called in React, it recreates the `signalJSX`.

You may not need this use case, but it does work. Signalist is designed to cater to gradual migration of legacy React projects, hence its flexibility in accommodating various use cases.

You can use react main api:

```tsx
import { useState } from "react";
import { computed, useSignal, signalJSX } from "signalist";

function MyComponent() {
const [state, setState] = useState(0);
const count = useSignal(0);

useEffect(() => {
console.log("I mount");
() => {
console.log("I unmount");
};
}, []);

return signalJSX(


{/* slowly: */}
setState(state + 1)}> add react state

count: {count}


{/* faster: */}
(count.value += 1)}> add count
,
);
}
```

# signalStorage

`signalStorage` is a React component that can automatically persist state to local storage and supports secure SSR hydration. To ensure successful SSR hydration, it's use the `useInitStorage` hook in conjunction.

First, use the `useInitStorage` hooks at the root component of your application:

```jsx
import { useInitStorage } from 'signalist';

const

function App() {
useInitStorage();
return (


{/* your app */}

);
}
```

Then, you can use the `signalStorage` hook in any component that needs to persist state, signalStorage will automatically persist to localhost, and will be reloaded after useInitStorage is executed:

```jsx
import { signalStorage } from "signalist";

// auto load
const clicks = signalStorage("clicks", "");

function Counter() {
return (


Count: {clicks}


{/* auto save in change */}
(clicks.value += 1)}>Increment

);
}
```

## License

Signalist is licensed under the MIT License. See the [LICENSE](./LICENSE) file for more information.

## Contributing

Contributions are welcome! See the [CONTRIBUTING](./CONTRIBUTING.md) file for more information.