Skip to content

agrison/redux4j

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Apr 17, 2021
c10ed4a · Apr 17, 2021

History

22 Commits
Apr 17, 2021
Apr 14, 2021
Apr 14, 2021
Apr 17, 2021
Apr 17, 2021

Repository files navigation

Redux in Java

redux4j codecov

Using Java and Vavr.

Features

  • Store
  • Reducer
  • CombineReducers
  • Middlewares

Install

<dependency>
  <groupId>me.grison</groupId>
  <artifactId>redux4j</artifactId>
  <version>1.0</version>
</dependency>

Counter example

public class Counter {
    // Actions
    static final String INC = "INC";
    static final String DEC = "DEC";

    // this is our reducer which increments if INC, decrement if DEC
    // and does nothing otherwise
    final Reducer<String, Integer> reducer =
            (action, state) -> state + switch (action) {
                case INC -> 1;
                case DEC -> -1;
                default -> 0;
            };

    public void foo() {
        // This is our store with its initial state of zero and the reducer seen above
        Store<Integer, String> store = Redux.createStore(0, reducer);

        // dispatch an INC action
        store.dispatch(INC);
        store.getState(); // 1

        // dispatch an DEC action
        store.dispatch(DEC);
        store.getState(); // 0
    }
}

Middlewares

public class Counter {

    final Middleware<Integer, String> middleware = (store, action, next) -> {
        System.out.println("Before " + store.getState());
        next.accept(store, action, null);
        System.out.println("After " + store.getState());
    };

    public void foo() {
        Store<Integer, String> store = Redux.createStore(0, reducer, middleware);

        store.dispatch(INC);
    }
}

Outputs:

Before 0
After 1

Combine Reducers

public class Foo {
	Reducer<String, String> concatBar =
			(action, state) -> "CONCAT".equals(action) ? state + "bar" : state;

	Reducer<String, Integer> plus2 =
			(action, state) -> "PLUS".equals(action) ? state + 2 : state;

	Reducer<String, List<String>> addFoo = (action, state) -> {
					if ("ADD".equals(action))
						state.add("foo");
					return state;
				};

	Reducer reducers = Redux.combineReducers(Tuple.of("str", concatBar), Tuple.of("int", plus2), Tuple.of("list", addFoo));

	@Test
	public void testCombineReducersMap() {
		Map<String, Object> initialState = new HashMap<String, Object>() {{
			put("str", "foo");
			put("int", 1);
			put("list", new ArrayList<String>());
		}};
		Store<Map<String,Object>, String> store = Redux.createStore(initialState, reducers);

		assertThat(store.getState().get("str"), equalTo("foo"));
		store.dispatch("CONCAT");
		assertThat(store.getState().get("str"), equalTo("foobar"));

		assertThat(store.getState().get("int"), equalTo(1));
		store.dispatch("PLUS");
		assertThat(store.getState().get("int"), equalTo(3));
		store.dispatch("PLUS");
		assertThat(store.getState().get("int"), equalTo(5));

		store.dispatch("CONCAT");
		assertThat(store.getState().get("str"), equalTo("foobarbar"));

		assertThat(store.getState().get("list"), equalTo(Arrays.asList()));
		store.dispatch("ADD");
		assertThat(store.getState().get("list"), equalTo(Arrays.asList("foo")));
		store.dispatch("ADD");
		assertThat(store.getState().get("list"), equalTo(Arrays.asList("foo", "foo")));
	}

	// same with a javabean with getters/setters
}