Изменить значение свойства в объекте с линзами Рамда - PullRequest
3 голосов
/ 15 мая 2019

Я хотел бы знать, как изменить свойства объекта с помощью линз Ramda.

В настоящее время у меня глубокое состояние:

buckets[
    blocks[
        messages[
            replies [
                {id: 0, text: 'text 0', value: 'simple value 0'},
                {id: 1, text: 'text 1', value: 'simple value 1'},
                {id: 2, text: 'text 2', value: 'simple value 2'},
                ...
            ]
        ]
    ]
]

У меня есть основная полезная нагрузка. Я хотел бы получить свойство и значение и установить старое значение новым значением в моем состоянии, например, с такой полезной нагрузкой:

{text: 'new_text'} или же {значение: 'новое_значение'}

В моем редукторе у меня есть это:

case SEQUENCES.UPDATE_REPLY_ON_BLOCK :
// payload => {text: 'new_text'}, or {value: 'new_value'}, or anyway...

let key = Object.keys(payload)[0];
let value = payload[key];

return R.over(
  R.lensPath(["buckets", 0, "blocks", 0, "messages", 0, "replies", 0, key]),
  R.set(value),
  state
);

Я пытался с Merge:

return R.over(
    R.lensPath(["buckets", 0, "blocks", 0, "messages", 0, "replies", 0),
    R.merge(payload),
    state,
);

Но тот же результат: состояние не изменено, и у меня нет ошибки.

Может быть решено с помощью mergeDeepLeft:

//payload => {value: 'new_value'}

return R.over(
    R.lensPath(["buckets", 0, "blocks", 0, "messages", 0, "replies", 0),
    R.mergeDeepLeft(payload),
    state,
);

1 Ответ

3 голосов
/ 15 мая 2019

Ты рядом. Проблема в том, что R.set и R.over используются для двух разных задач. Вам не нужно over здесь. Вместо этого ваша внешняя функция должна быть set, а второй параметр - это значение, которое вы хотите установить для объектива:

const payload = {text: 'new_text'}
const key = Object.keys(payload)[0];
const value = payload[key];

const state = {buckets: [{blocks: [{messages: [{replies: [{id: 0, text: 'text 0', value: 'simple value 0'}, {id: 1, text: 'text 1', value: 'simple value 1'}, {id: 2, text: 'text 2', value: 'simple value 2'}]}]}]}]}

console.log(
    R.set(
        R.lensPath(['buckets', 0, 'blocks', 0, 'messages', 0, 'replies', 0, key]),
        value,
        state,
    )
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>

Вы используете over, когда хотите настроить его на основе уже существующего значения, передав функцию из старого значения в новое значение в качестве второго параметра. Например, R.over(myLens, R.toUpper, obj):

const payload = {text: 'new_text'}
const key = Object.keys(payload)[0];
const value = payload[key];

const state = {buckets: [{blocks: [{messages: [{replies: [{id: 0, text: 'text 0', value: 'simple value 0'}, {id: 1, text: 'text 1', value: 'simple value 1'}, {id: 2, text: 'text 2', value: 'simple value 2'}]}]}]}]}

console.log(
    R.over(
        R.lensPath(['buckets', 0, 'blocks', 0, 'messages', 0, 'replies', 0, key]),
        R.toUpper,
        state,
    )
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
...